diff options
Diffstat (limited to 'spectro/inst.c')
-rw-r--r-- | spectro/inst.c | 222 |
1 files changed, 198 insertions, 24 deletions
diff --git a/spectro/inst.c b/spectro/inst.c index d57a84a..2d3adc3 100644 --- a/spectro/inst.c +++ b/spectro/inst.c @@ -49,18 +49,21 @@ #include "ccmx.h" #include "ccss.h" #include "conv.h" -#include "insttypes.h" +#include "insttypes.h" #include "icoms.h" #include "inst.h" #include "insttypeinst.h" - #include "sort.h" -#ifdef ENABLE_SERIAL +#if defined(ENABLE_FAST_SERIAL) +instType fast_ser_inst_type(icoms *p, int tryhard, + inst_code (*uicallback)(void *cntx, inst_ui_purp purp), void *cntx); +# if defined(ENABLE_SERIAL) static instType ser_inst_type(icoms *p, -inst_code (*uicallback)(void *cntx, inst_ui_purp purp), void *cntx); -#endif /* ENABLE_SERIAL */ + inst_code (*uicallback)(void *cntx, inst_ui_purp purp), void *cntx); +# endif /* ENABLE_SERIAL */ +#endif /* ENABLE_FAST_SERIAL */ /* ------------------------------------ */ /* Default methods for instrument class */ @@ -336,10 +339,10 @@ inst_cal_type *n_cals, inst_cal_type *a_cals) { if (n_cals != NULL) - *n_cals = inst_calc_none; + *n_cals = inst_calt_none; if (a_cals != NULL) - *a_cals = inst_mode_none; + *a_cals = inst_calt_none; return inst_ok; } @@ -521,13 +524,23 @@ void *cntx /* Context for callback */ icoms *icom; inst *p = NULL; + a1logd(log, 2, "new_inst: called with path '%s'\n",path->name); + if ((icom = new_icoms(path, log)) == NULL) { + a1logd(log, 2, "new_inst: new_icoms failed to open it\n"); return NULL; } + /* Set instrument type from USB port, if not specified */ itype = icom->itype; /* Instrument type if its known from usb/hid */ -#ifdef ENABLE_SERIAL + +#if defined(ENABLE_FAST_SERIAL) + if (itype == instUnknown && !nocoms && icom->fast) + itype = fast_ser_inst_type(icom, 1, uicallback, cntx); /* Else type from serial */ +#endif /* ENABLE_FAST_SERIAL */ + +#if defined(ENABLE_SERIAL) if (itype == instUnknown && !nocoms) itype = ser_inst_type(icom, uicallback, cntx); /* Else type from serial */ #endif /* ENABLE_SERIAL */ @@ -552,6 +565,12 @@ void *cntx /* Context for callback */ */ #endif /* ENABLE_SERIAL */ +#ifdef ENABLE_FAST_SERIAL + if (itype == instSpecbos1201 + || itype == instSpecbos) + p = (inst *)new_specbos(icom, itype); +#endif /* ENABLE_SERIAL */ + #ifdef ENABLE_USB if (itype == instDTP94) p = (inst *)new_dtp92(icom, itype); @@ -585,9 +604,14 @@ void *cntx /* Context for callback */ p = (inst *)new_colorhug(icom, itype); #endif /* ENABLE_USB */ + + /* Nothing matched */ - if (p == NULL) + if (p == NULL) { + a1logd(log, 2, "new_inst: instrument type not recognised\n"); + icom->del(icom); return NULL; + } /* Add default methods if constructor did not supply them */ if (p->init_coms == NULL) @@ -696,6 +720,35 @@ void *cntx /* Context for callback */ R Raw sensor values */ +/* Default display technology strings: + + "Color Matching Function" + "Custom" + "CRT" + "LCD CCFL IPS" + "LCD CCFL VPA" + "LCD CCFL TFT" + "LCD CCFL Wide Gamut IPS" + "LCD CCFL Wide Gamut VPA" + "LCD CCFL Wide Gamut TFT" + "LCD White LED IPS" + "LCD White LED VPA" + "LCD White LED TFT" + "LCD RGB LED IPS" + "LCD RGB LED VPA" + "LCD RGB LED TFT" + "LED OLED" + "LED AMOLED" + "Plasma" + "LCD RG Phosphor" + "Projector RGB Filter Wheel" + "Projector RGBW Filter Wheel" + "Projector RGBCMY Filter Wheel" + "Projector" + "Unknown" + + */ + /* Free a display type list */ void inst_del_disptype_list(inst_disptypesel *list, int no) { @@ -751,17 +804,31 @@ static inst_disptypesel *expand_dlist(inst_disptypesel *list, int nlist, int *na if no selector remain, allocate a free one. 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. */ /* Set the selection characters */ /* return NZ if we have run out */ -static int set_sel(char *sel, char *usels, int *k, char *asels) { - char *d, *s; +/* If flag == 0, deal with all selectors */ +/* If flag == 1, deal with just primary selectors */ +/* If flag == 2, deal with just secondary selectors */ +static int set_sel(int flag, char *sel, char *usels, int *k, char *asels) { + char *d, *s, i; /* First remove any used chars from selector */ - for (d = s = sel; *s != '\000'; s++) { - if (usels[*s] == 0) + for (i = 0, d = s = sel; *s != '\000'; s++, i++) { + if ((flag == 2 && i == 0) /* Ignore and keep primary selector */ + || (flag == 1 && i == 1)) { /* Ignore and keep secondary selectors */ *d++ = *s; + continue; + } + if (usels[*s] == 0) { /* If selector is not currently used */ + *d++ = *s; + usels[*s] = 1; + } } *d = '\000'; @@ -805,9 +872,9 @@ int doccmx /* Add matching installed ccmx files */ for (i = 0; i < 256; i++) usels[i] = 0; - k = 0; + k = 0; /* Next selector index */ - /* Add entries from the static list */ + /* Add entries from the static list and their primary selectors */ /* Count the number in the static list */ for (i = 0; !(sdtlist[i].flags & inst_dtflags_end); i++) { @@ -816,14 +883,12 @@ int doccmx /* Add matching installed ccmx files */ list[nlist-1] = sdtlist[i]; /* Struct copy */ - if (set_sel(list[nlist-1].sel, usels, &k, asels)) { + if (set_sel(1, list[nlist-1].sel, usels, &k, asels)) { a1loge(p->log, 1, "inst_creat_disptype_list run out of selectors\n"); break; } } - k = 0; /* Next selector index */ - /* Add any ccss's */ if (doccss) { iccss *ss_list; @@ -843,7 +908,7 @@ int doccmx /* Add matching installed ccmx files */ strncpy(list[nlist-1].sel, ss_list[i].sel, INST_DTYPE_SEL_LEN); list[nlist-1].sel[INST_DTYPE_SEL_LEN-1] = '\000'; } - if (set_sel(list[nlist-1].sel, usels, &k, asels)) { + if (set_sel(1, list[nlist-1].sel, usels, &k, asels)) { a1loge(p->log, 1, "inst_creat_disptype_list run out of selectors\n"); break; } @@ -889,7 +954,7 @@ int doccmx /* Add matching installed ccmx files */ strncpy(list[nlist-1].sel, ss_list[i].sel, INST_DTYPE_SEL_LEN); list[nlist-1].sel[INST_DTYPE_SEL_LEN-1] = '\000'; } - if (set_sel(list[nlist-1].sel, usels, &k, asels)) { + if (set_sel(1, list[nlist-1].sel, usels, &k, asels)) { a1loge(p->log, 1, "inst_creat_disptype_list run out of selectors\n"); break; } @@ -902,6 +967,11 @@ int doccmx /* Add matching installed ccmx files */ } } + /* Verify or delete any secondary selectors from the list */ + for (i = 0; i < nlist; i++) { + set_sel(2, list[i].sel, usels, &k, asels); + } + if (pndtlist != NULL) *pndtlist = nlist; if (pdtlist != NULL) @@ -963,6 +1033,7 @@ iccmx *list_iccmx(char *inst, int *no) { if (inst != NULL && cs->inst != NULL && strcmp(inst, cs->inst) != 0) continue; + a1logd(g_log, 5, "Reading '%s'\n",paths[i]); if ((tech = cs->tech) == NULL) tech = ""; if ((disp = cs->disp) == NULL) @@ -1089,6 +1160,7 @@ iccss *list_iccss(int *no) { continue; /* Skip any unreadable ccss's */ } + a1logd(g_log, 5, "Reading '%s'\n",paths[i]); if ((tech = cs->tech) == NULL) tech = ""; if ((disp = cs->disp) == NULL) @@ -1170,6 +1242,102 @@ void free_iccss(iccss *list) { } /* ============================================================= */ +/* Detect fast serial instruments */ + +#ifdef ENABLE_FAST_SERIAL +static void hex2bin(char *buf, int len); + +/* Heuristicly determine the instrument type for */ +/* a fast serial connection, and instUnknown if not serial. */ +/* Set it in icoms and also return it. */ +instType fast_ser_inst_type( + icoms *p, + int tryhard, + inst_code (*uicallback)(void *cntx, inst_ui_purp purp), /* optional uicallback */ + void *cntx /* Context for callback */ +) { + instType rv = instUnknown; + char buf[100]; + baud_rate brt[] = { baud_921600, baud_115200, baud_38400, baud_nc }; + unsigned int etime; + unsigned int i; + int se, len; + + if (p->port_type(p) != icomt_serial + && p->port_type(p) != icomt_usbserial) + return p->itype; + + /* The tick to give up on */ + etime = msec_time() + (long)(2000.0 + 0.5); + + a1logd(p->log, 1, "fser_inst_type: Trying different baud rates (%u msec to go)\n",etime - msec_time()); + + /* Until we time out, find the correct baud rate */ + for (i = 0; msec_time() < etime; i++) { + if (brt[i] == baud_nc) { + i = 0; + if (!tryhard) + break; /* try only once */ + } + 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]); + + /* See if it's a JETI specbos */ + if ((se = p->write_read(p, "*idn?\r", buf, 100, "\r", 1, 0.050)) != 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; + } + 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"); + 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"); + rv = instSpecbos; + break; + } + } + + if (rv == instUnknown + && msec_time() >= etime) { /* We haven't established comms */ + a1logd(p->log, 5, "fser_inst_type: Failed to establish coms\n"); + p->itype = rv; + return instUnknown; + } + + a1logd(p->log, 5, "fser_inst_type: Instrument type is '%s'\n", inst_name(rv)); + + p->itype = rv; + + return rv; +} + +#endif /* ENABLE_FAST_SERIAL */ + +/* ============================================================= */ +/* Detect serial instruments */ #ifdef ENABLE_SERIAL static void hex2bin(char *buf, int len); @@ -1217,7 +1385,7 @@ static instType ser_inst_type( } // a1logd(p->log, 5, "brt = %d\n",brt[i]); - if ((se = p->write_read(p, ";D024\r\n", buf, 100, '\r', 1, 0.5)) != inst_ok) { + if ((se = p->write_read(p, ";D024\r\n", buf, 100, "\r", 1, 0.5)) != inst_ok) { /* Check for user abort */ if (uicallback != NULL) { inst_code ev; @@ -1226,6 +1394,7 @@ static instType ser_inst_type( return instUnknown; } } + continue; } len = strlen(buf); @@ -1254,7 +1423,8 @@ static instType ser_inst_type( } } - if (msec_time() >= etime) { /* We haven't established comms */ + if (rv == instUnknown + && msec_time() >= etime) { /* We haven't established comms */ a1logd(p->log, 5, "ser_inst_type: Failed to establish coms\n"); return instUnknown; } @@ -1269,7 +1439,7 @@ static instType ser_inst_type( /* SpectroScan */ if (ss) { rv = instSpectroScan; - if ((se = p->write_read(p, ";D030\r\n", buf, 100, '\n', 1, 1.5)) == 0) { + if ((se = p->write_read(p, ";D030\r\n", buf, 100, "\n", 1, 1.5)) == 0) { if (strlen(buf) >= 41) { hex2bin(&buf[5], 12); // a1logd(p->log, 5, "spectroscan type = '%s'\n",buf); @@ -1281,7 +1451,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", buf, 100, '>', 1, 2.5)) != 0) + if ((se = p->write_read(p, "SV\r\n", buf, 100, ">", 1, 2.5)) != 0) return instUnknown; if (strlen(buf) >= 12) { @@ -1311,6 +1481,10 @@ static instType ser_inst_type( return rv; } +#endif /* ENABLE_SERIAL */ + +#if defined(ENABLE_SERIAL) || defined(ENABLE_FAST_SERIAL) + /* Convert an ASCII Hex character to an integer. */ static int h2b(char c) { if (c >= '0' && c <= '9') |