summaryrefslogtreecommitdiff
path: root/spectro/i1disp.c
diff options
context:
space:
mode:
Diffstat (limited to 'spectro/i1disp.c')
-rw-r--r--spectro/i1disp.c297
1 files changed, 182 insertions, 115 deletions
diff --git a/spectro/i1disp.c b/spectro/i1disp.c
index cb5472b..e9a375e 100644
--- a/spectro/i1disp.c
+++ b/spectro/i1disp.c
@@ -53,7 +53,6 @@
#include "icoms.h"
#include "i1disp.h"
-static void dump_bytes(a1log *log, char *pfx, unsigned char *buf, int base, int len);
static inst_code i1disp_interp_code(inst *pp, int ec);
static inst_code i1disp_do_fcal_setit(i1disp *p);
static inst_code i1disp_check_unlock(i1disp *p);
@@ -108,6 +107,7 @@ typedef enum {
i1d_m_rgb_edge_2 = 0x16, /* -:W Measure RGB Edge (16 bit) */
+ /* Different meanings for different devices ? */
i1d_set_pll_p = 0x11, /* SS:- Set PLL period */
i1d_get_pll_p = 0x12, /* -:W Get PLL period */
@@ -118,9 +118,11 @@ typedef enum {
i1d_wrxreg = 0x13, /* SB:- Write an extra register value */
i1d_rdxreg = 0x14, /* S:B Read an extra register value */
-
- i1d_rdexreg = 0x19 /* BS:B Smile: Read an extended register value */
/* The address range overlapps i1d_rdreg */
+ /* Smile */
+// i1d_xxxxxxx = 0x18, /* XXX:X Unknown */
+ i1d_rdexreg = 0x19 /* BS:BBBB Read an extended register value */
+
} i1DispCC;
/* Do a command/response exchange with the i1disp. */
@@ -1324,6 +1326,9 @@ i1disp_read_refrate(
if (p->dtype != 1)
return inst_unsupported;
+ if (ref_rate != NULL)
+ *ref_rate = 0.0;
+
/* Average a few refresh period readings */
for (i = 0; i < p->nmeasprds; i++) {
int mp;
@@ -1406,6 +1411,7 @@ i1disp_check_unlock(
{ { 'O','b','i','w' }, &p->hpdream }, /* "Obiw" HP DreamColor */
{ { 'C','M','X','2' }, &p->calmanx2 }, /* "CMX2" Calman X2 */
{ { 0x24,0xb6,0xb5,0x13 }, NULL }, /* ColorMunki Smile */
+ { { 'S','p','C','3' }, NULL }, /* SpectraCal C3 (Based on Smile) */
{ { 'R','G','B','c' }, NULL }, /* */
{ { 'C','E','C','5' }, NULL }, /* */
{ { 'C','M','C','5' }, NULL }, /* */
@@ -1491,11 +1497,13 @@ i1disp_check_unlock(
} else if (ver >= 6.0 && ver <= 6.29 && vv == 'L') {
p->dtype = 1; /* Eye-One Display 2 */
- } else if (ver >= 6.0 && ver <= 6.29 && vv == 'M') {
+ } else if (ver >= 6.0 && ver <= 6.29
+ && (vv = 0xff || vv == 'M')) { // Faulty Smile's have vv = 0xff
/* ColorMunki Create ? */
/* ColorMunki Smile */
if (p->dtype == 0) /* Not sure if this is set by Create */
p->dtype = 1;
+
} else {
/* Reject any version or model we don't know about */
a1logv(p->log, 1, "Version string = %3.1f\nID character = 0x%02x = '%c'\n",ver,vv,vv);
@@ -1785,41 +1793,42 @@ i1disp_init_inst(inst *pp) {
if ((ev = i1disp_check_unlock(p)) != inst_ok)
return ev;
- /* Read all the registers and store their contents */
- if ((ev = i1disp_read_all_regs(p)) != inst_ok)
- return ev;
+ if (p->log->debug >= 3) {
-#ifdef NEVER
- /* Dump all the register space */
- if (p->dtype < 2) {
- unsigned char buf[0x200];
- int i, len;
-
- len = 128;
- if (p->dtype != 0)
- len = 160;
-
- for (i = 0; i < len; i++) {
- int v;
- if ((ev = i1disp_rdreg_byte(p, &v, i)) != inst_ok) {
- return ev;
+ /* Dump all the register space */
+ if (p->dtype < 2) {
+ unsigned char buf[0x200];
+ int i, len;
+
+ len = 128;
+ if (p->dtype != 0)
+ len = 160;
+
+ for (i = 0; i < len; i++) {
+ int v;
+ if ((ev = i1disp_rdreg_byte(p, &v, i)) != inst_ok) {
+ return ev;
+ }
+ buf[i] = v;
}
- buf[i] = v;
- }
- dump_bytes(p->log, "dump:", buf, 0, len);
-
- /* Dump ColorMunki Smile extended range */
- /* Main difference is Ascii serial number + other minor unknown */
- } else {
- unsigned char buf[0x200];
-
+ adump_bytes(p->log, "dump:", buf, 0, len);
- if ((ev = i1disp_rdexreg_bytes(p, buf, 0, 0x200)) != inst_ok) {
- return ev;
+ /* Dump ColorMunki Smile extended range */
+ /* Main difference is Ascii serial number + other minor unknown */
+ } else {
+ unsigned char buf[0x200];
+
+
+ if ((ev = i1disp_rdexreg_bytes(p, buf, 0, 0x200)) != inst_ok) {
+ return ev;
+ }
+ adump_bytes(p->log, "dump:", buf, 0, 0x200);
}
- dump_bytes(p->log, "dump:", buf, 0, 0x200);
}
-#endif /* NEVER */
+
+ /* Read all the registers and store their contents */
+ if ((ev = i1disp_read_all_regs(p)) != inst_ok)
+ return ev;
if ((ev = i1disp_compute_factors(p)) != inst_ok)
return ev;
@@ -1884,9 +1893,14 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
return rv; /* Abort */
}
+
/* Read the XYZ value */
- if ((rv = i1disp_take_XYZ_measurement(p, val->XYZ)) != inst_ok)
+ rv = i1disp_take_XYZ_measurement(p, val->XYZ);
+
+ if (rv != inst_ok)
return rv;
+
+
/* This may not change anything since instrument may clamp */
if (clamp)
icmClamp3(val->XYZ, val->XYZ);
@@ -1905,28 +1919,44 @@ instClamping clamp) { /* NZ if clamp XYZ/Lab to be +ve */
return rv;
}
+static inst_code set_base_disp_type(i1disp *p, int cbid);
+
/* Insert a colorimetric correction matrix in the instrument XYZ readings */
/* This is only valid for colorimetric instruments. */
/* To remove the matrix, pass NULL for the filter filename */
inst_code i1disp_col_cor_mat(
inst *pp,
+disptech dtech, /* Use disptech_unknown if not known */ \
+int cbid, /* Calibration display type base ID, 1 if unknown */\
double mtx[3][3]
) {
i1disp *p = (i1disp *)pp;
+ inst_code ev;
if (!p->gotcoms)
return inst_no_coms;
if (!p->inited)
return inst_no_init;
- if (mtx == NULL) {
+ if ((ev = set_base_disp_type(p, cbid)) != inst_ok)
+ return ev;
+ if (mtx == NULL)
icmSetUnity3x3(p->ccmat);
- } else {
- if (p->cbid == 0) {
- a1loge(p->log, 1, "spyd2: can't set col_cor_mat over non-base display type\n");
- return inst_wrong_setup;
- }
+ else
icmCpy3x3(p->ccmat, mtx);
+ p->dtech = dtech;
+ p->refrmode = disptech_get_id(dtech)->refr;
+ p->cbid = 0; /* Can't be base type now */
+
+ if (p->log->debug >= 4) {
+ a1logd(p->log,4,"ccmat = %f %f %f\n",
+ p->ccmat[0][0], p->ccmat[0][1], p->ccmat[0][2]);
+ a1logd(p->log,4," %f %f %f\n",
+ p->ccmat[1][0], p->ccmat[1][1], p->ccmat[1][2]);
+ a1logd(p->log,4," %f %f %f\n\n",
+ p->ccmat[2][0], p->ccmat[2][1], p->ccmat[2][2]);
+ a1logd(p->log,4,"ucbid = %d, cbid = %d\n",p->ucbid, p->cbid);
+ a1logd(p->log,4,"\n");
}
return inst_ok;
@@ -2059,6 +2089,7 @@ double *ref_rate
i1disp *p = (i1disp *)pp;
if (p->refrvalid) {
*ref_rate = p->refrate;
+
return inst_ok;
} else if (p->rrset) {
*ref_rate = 0.0;
@@ -2213,7 +2244,7 @@ i1disp_del(inst *pp) {
}
/* Return the instrument capabilities */
-void i1disp_capabilities(inst *pp,
+static void i1disp_capabilities(inst *pp,
inst_mode *pcap1,
inst2_capability *pcap2,
inst3_capability *pcap3) {
@@ -2254,7 +2285,7 @@ inst3_capability *pcap3) {
}
/* Check device measurement mode */
-inst_code i1disp_check_mode(inst *pp, inst_mode m) {
+static inst_code i1disp_check_mode(inst *pp, inst_mode m) {
i1disp *p = (i1disp *)pp;
inst_mode cap;
@@ -2279,7 +2310,7 @@ inst_code i1disp_check_mode(inst *pp, inst_mode m) {
}
/* Set device measurement mode */
-inst_code i1disp_set_mode(inst *pp, inst_mode m) {
+static inst_code i1disp_set_mode(inst *pp, inst_mode m) {
i1disp *p = (i1disp *)pp;
inst_code ev;
@@ -2296,21 +2327,23 @@ inst_code i1disp_set_mode(inst *pp, inst_mode m) {
return inst_ok;
}
-inst_disptypesel i1disp_disptypesel[3] = {
+static inst_disptypesel i1disp_disptypesel[3] = {
{
inst_dtflags_default,
1,
"l",
"LCD display",
0,
+ disptech_lcd,
0
},
{
inst_dtflags_none, /* flags */
- 2, /* cbix */
+ 2, /* cbid */
"c", /* sel */
"CRT display", /* desc */
1, /* refr */
+ disptech_crt, /* disptype */
1 /* ix */
},
{
@@ -2319,18 +2352,20 @@ inst_disptypesel i1disp_disptypesel[3] = {
"",
"",
0,
+ disptech_none,
0
}
};
-inst_disptypesel smile_disptypesel[3] = {
+static inst_disptypesel smile_disptypesel[3] = {
{
inst_dtflags_default, /* flags */
- 1, /* cbix */
+ 1, /* cbid */
"fl", /* sel */
"LCD with CCFL backlight", /* desc */
0, /* refr */
+ disptech_lcd_ccfl, /* disptype */
1 /* ix */
},
{
@@ -2339,6 +2374,7 @@ inst_disptypesel smile_disptypesel[3] = {
"e",
"LCD with White LED backlight",
0,
+ disptech_lcd_wled,
0
},
{
@@ -2347,6 +2383,7 @@ inst_disptypesel smile_disptypesel[3] = {
"",
"",
0,
+ disptech_none,
0
}
};
@@ -2371,7 +2408,7 @@ int recreate /* nz to re-check for new ccmx & ccss files */
i1disp *p = (i1disp *)pp;
inst_code rv = inst_ok;
- /* Create/Re-create a current list of abailable display types */
+ /* Create/Re-create a current list of available display types */
if (p->dtlist == NULL || recreate) {
if ((rv = inst_creat_disptype_list(pp, &p->ndtlist, &p->dtlist,
p->_dtlist, 0 /* doccss*/, 1 /* doccmx */)) != inst_ok)
@@ -2391,8 +2428,24 @@ int recreate /* nz to re-check for new ccmx & ccss files */
static inst_code set_disp_type(i1disp *p, inst_disptypesel *dentry) {
int refrmode;
- p->icx = dentry->ix;
- p->cbid = dentry->cbid;
+ if (dentry->flags & inst_dtflags_ccmx) {
+ inst_code ev;
+ if ((ev = set_base_disp_type(p, dentry->cc_cbid)) != inst_ok)
+ return ev;
+ icmCpy3x3(p->ccmat, dentry->mat);
+ p->dtech = dentry->dtech;
+ p->cbid = 0; /* Can't be a base type now */
+
+ } else { /* Native */
+
+ p->icx = dentry->ix;
+ p->dtech = dentry->dtech;
+ p->cbid = dentry->cbid;
+ p->ucbid = dentry->cbid; /* This is underying base if dentry is base selection */
+ icmSetUnity3x3(p->ccmat);
+ }
+
+ /* Implement any refresh mode change */
refrmode = dentry->refr;
if ( IMODETST(p->mode, inst_mode_emis_norefresh_ovd)) { /* Must test this first! */
@@ -2407,15 +2460,50 @@ static inst_code set_disp_type(i1disp *p, inst_disptypesel *dentry) {
}
p->refrmode = refrmode;
- if (dentry->flags & inst_dtflags_ccmx) {
- icmCpy3x3(p->ccmat, dentry->mat);
- } else {
- icmSetUnity3x3(p->ccmat);
+ if (p->log->debug >= 4) {
+ a1logd(p->log,4,"ccmat = %f %f %f\n",
+ p->ccmat[0][0], p->ccmat[0][1], p->ccmat[0][2]);
+ a1logd(p->log,4," %f %f %f\n",
+ p->ccmat[1][0], p->ccmat[1][1], p->ccmat[1][2]);
+ a1logd(p->log,4," %f %f %f\n\n",
+ p->ccmat[2][0], p->ccmat[2][1], p->ccmat[2][2]);
+ a1logd(p->log,4,"ucbid = %d, cbid = %d\n",p->ucbid, p->cbid);
+ a1logd(p->log,4,"\n");
+ }
+
+ return inst_ok;
+}
+
+/* Set the display type */
+static inst_code i1disp_set_disptype(inst *pp, int ix) {
+ i1disp *p = (i1disp *)pp;
+ inst_code ev;
+ inst_disptypesel *dentry;
+
+ if (!p->gotcoms)
+ return inst_no_coms;
+ if (!p->inited)
+ return inst_no_init;
+
+ if (p->dtlist == NULL) {
+ if ((ev = inst_creat_disptype_list(pp, &p->ndtlist, &p->dtlist,
+ p->_dtlist, 0 /* doccss*/, 1 /* doccmx */)) != inst_ok)
+ return ev;
+ }
+
+ if (ix < 0 || ix >= p->ndtlist)
+ return inst_unsupported;
+
+ dentry = &p->dtlist[ix];
+
+ if ((ev = set_disp_type(p, dentry)) != inst_ok) {
+ return ev;
}
return inst_ok;
}
+/* Get the disptech corresponding to the current */
/* Setup the default display type */
static inst_code set_default_disp_type(i1disp *p) {
inst_code ev;
@@ -2442,35 +2530,55 @@ static inst_code set_default_disp_type(i1disp *p) {
return inst_ok;
}
-/* Set the display type */
-static inst_code i1disp_set_disptype(inst *pp, int ix) {
- i1disp *p = (i1disp *)pp;
+/* Setup the display type to the given base type */
+static inst_code set_base_disp_type(i1disp *p, int cbid) {
inst_code ev;
- inst_disptypesel *dentry;
-
- if (!p->gotcoms)
- return inst_no_coms;
- if (!p->inited)
- return inst_no_init;
+ int i;
+ if (cbid == 0) {
+ a1loge(p->log, 1, "i1disp set_base_disp_type: can't set base display type of 0\n");
+ return inst_wrong_setup;
+ }
if (p->dtlist == NULL) {
- if ((ev = inst_creat_disptype_list(pp, &p->ndtlist, &p->dtlist,
- p->_dtlist, 1 /* doccss*/, 1 /* doccmx */)) != inst_ok)
+ if ((ev = inst_creat_disptype_list((inst *)p, &p->ndtlist, &p->dtlist,
+ i1disp_disptypesel, 0 /* doccss*/, 1 /* doccmx */)) != inst_ok)
return ev;
}
- if (ix < 0 || ix >= p->ndtlist)
- return inst_unsupported;
-
- dentry = &p->dtlist[ix];
-
- if ((ev = set_disp_type(p, dentry)) != inst_ok) {
+ for (i = 0; !(p->dtlist[i].flags & inst_dtflags_end); i++) {
+ if (!(p->dtlist[i].flags & inst_dtflags_ccmx) /* Prevent infinite recursion */
+ && p->dtlist[i].cbid == cbid)
+ break;
+ }
+ if (p->dtlist[i].flags & inst_dtflags_end) {
+ a1loge(p->log, 1, "set_base_disp_type: failed to find cbid %d!\n",cbid);
+ return inst_wrong_setup;
+ }
+ if ((ev = set_disp_type(p, &p->dtlist[i])) != inst_ok) {
return ev;
}
return inst_ok;
}
+/* Get the disptech and other corresponding info for the current */
+/* selected display type. Returns disptype_unknown by default. */
+/* Because refrmode can be overridden, it may not match the refrmode */
+/* of the dtech. (Pointers may be NULL if not needed) */
+static inst_code i1disp_get_disptechi(
+inst *pp,
+disptech *dtech,
+int *refrmode,
+int *cbid) {
+ i1disp *p = (i1disp *)pp;
+ if (dtech != NULL)
+ *dtech = p->dtech;
+ if (refrmode != NULL)
+ *refrmode = p->refrmode;
+ if (cbid != NULL)
+ *cbid = p->cbid;
+ return inst_ok;
+}
/*
* set or reset an optional mode
@@ -2484,24 +2592,6 @@ i1disp_get_set_opt(inst *pp, inst_opt_type m, ...)
i1disp *p = (i1disp *)pp;
inst_code ev;
- /* Get the display type information */
- if (m == inst_opt_get_dtinfo) {
- va_list args;
- int *refrmode, *cbid;
-
- va_start(args, m);
- refrmode = va_arg(args, int *);
- cbid = va_arg(args, int *);
- va_end(args);
-
- if (refrmode != NULL)
- *refrmode = p->refrmode;
- if (cbid != NULL)
- *cbid = p->cbid;
-
- return inst_ok;
- }
-
/* Record the trigger mode */
if (m == inst_opt_trig_prog
|| m == inst_opt_trig_user) {
@@ -2527,6 +2617,7 @@ extern i1disp *new_i1disp(icoms *icom, instType itype) {
p->capabilities = i1disp_capabilities;
p->check_mode = i1disp_check_mode;
p->set_mode = i1disp_set_mode;
+ p->get_disptechi = i1disp_get_disptechi;
p->get_disptypesel = i1disp_get_disptypesel;
p->set_disptype = i1disp_set_disptype;
p->get_set_opt = i1disp_get_set_opt;
@@ -2552,37 +2643,13 @@ extern i1disp *new_i1disp(icoms *icom, instType itype) {
icmSetUnity3x3(p->ccmat); /* Set the colorimeter correction matrix to do nothing */
set_base_disptype_list(p);
+ p->dtech = disptech_unknown;
return p;
}
/* ---------------------------------------------------------------- */
-// Print bytes as hex to debug log */
-static void dump_bytes(a1log *log, char *pfx, unsigned char *buf, int base, int len) {
- int i, j, ii;
- char oline[200] = { '\000' }, *bp = oline;
- for (i = j = 0; i < len; i++) {
- if ((i % 16) == 0)
- bp += sprintf(bp,"%s%04x:",pfx,base+i);
- bp += sprintf(bp," %02x",buf[i]);
- if ((i+1) >= len || ((i+1) % 16) == 0) {
- for (ii = i; ((ii+1) % 16) != 0; ii++)
- bp += sprintf(bp," ");
- bp += sprintf(bp," ");
- for (; j <= i; j++) {
- if (!(buf[j] & 0x80) && isprint(buf[j]))
- bp += sprintf(bp,"%c",buf[j]);
- else
- bp += sprintf(bp,".");
- }
- bp += sprintf(bp,"\n");
- a1logd(log,0,"%s",oline);
- bp = oline;
- }
- }
-}
-