Utah Raster Toolkit  9999-git
URT Development version (post-3.1b)
qcr.c
Go to the documentation of this file.
1 /***************************************************************************
2  *
3  * qcr.c - Interface commands for a Matrix QCR-Z running on an HP 200/300
4  * machine running hp-ux version 5.1 or greater. It uses the device
5  * files /dev/qcrc for the command address, /dev/qcrd for the data
6  * address, and /dev/rhpib for the raw HPIB control.
7  *
8  *
9  * Mark J. Bradakis, University of Utah. Copyright 1987.
10  * Several modifications by John W. Peterson, U. of Utah, 1988.
11  *
12  ***************************************************************************/
13 
14 #include "qcr.h"
15 
18 
19 unsigned char response[BUFSIZ];
20 
21 /*************************************************************************
22  Wait for the HPIB SRQ line to be asserted (this is used by the QCR to
23  indicate completion of some operation).
24 */
25 
27 {
28  int i, status;
29 
30  io_timeout_ctl( qcr_raw, 90000000 ); /* 1.5 minutes */
31 
32  if (hpib_status_wait( qcr_raw, 1 ) == 0)
33  {
34  /* Clear the assertion. Assumes the default HPIB address. */
35  if ((status = hpib_spoll( qcr_raw, 2 )) == -1)
36  {
37  fprintf(stderr, "qcr.c: error during HPIB s-poll\n");
38  }
39  if ((status = hpib_spoll( qcr_raw, 3 )) == -1)
40  {
41  fprintf(stderr, "qcr.c: error during HPIB s-poll\n");
42  }
43  return(1);
44  }
45  else
46  fprintf(stderr, "qcr.c: HPIB timeout or error (no SRQ)\n");
47 }
48 
49 /*************************************************************************
50  write_qcr takes one of the command values (listed in qcr.h) and sends
51  it to the command address. If the command is not successfully written,
52  it jumps to the reset routine, hoping to salvage something.
53  */
54 
56 int cmd;
57 {
58  char ch[1];
59 
60  ch[0] = cmd & 0xff;
61  write(qcr_cmd,ch,1);
62  /* if (hpib_bus_status(qcr_raw,1) == 1) return(reset_qcr()); */
63  return(1); /* Assume success */
64 }
65 
66 
67 
68 /*************************************************************************
69  write_data: Set up the interface for large transfers using burst mode
70  HP-IB communications.
71 
72  */
73 
75 char *buff;
76 int len;
77 {
78  int stat;
79 
80  if (io_burst(qcr_data,1) != 0) /* Enable burst mode */
81  fprintf(stderr," write_data: burst mode on failed %d\n");
82 
83  stat = write(qcr_data,buff,len);
84  if (stat != len) fprintf(stderr," write_data: stat %d != %d (len)\n",
85  stat, len);
86 
87  /* if (hpib_bus_status(qcr_raw,1) == 1) return(reset_qcr()); */
88 
89  if (io_burst(qcr_data,0) != 0) /* Disable burst mode */
90  fprintf(stderr," write_data: burst mode off failed %d\n");
91 
92  return(stat); /* Assume success */
93 }
94 
95 
96 
97 /*************************************************************************
98  This routine opens the device files required for the QCR command port,
99  the data port and the raw hpib control device. It checks for the
100  existence of the device by an identify command.
101  */
102 
103 int
105 
106 short verbose;
107 {
108  int len;
109  char ch, *command;
110 
111  verbose_flag = verbose; /* Some control of output */
112 
113  if ((qcr_cmd = open ("/dev/qcrc", O_RDWR)) < 0)
114  {
115  fprintf(stderr,"Recorder command dev not opened: error = %d\n",errno);
116  return(-1);
117  }
118  if ((qcr_data = open ("/dev/qcrd", O_RDWR)) < 0)
119  {
120  fprintf(stderr,"Recorder data dev not opened: error = %d\n",errno);
121  return(-1);
122  }
123 
124  if ((qcr_raw = open ("/dev/rhpib", O_RDWR)) < 0)
125  {
126  fprintf(stderr,"/dev/rhpib not opened: error = %d\n",errno);
127  return(-1);
128  }
129  /* Check for response from the Matrix */
130 
132 
133  if (read(qcr_data,response,BUFSIZ) != IDLENGTH )
134  {
135  fprintf(stderr,"Error reading response from QCR, errno = %d\n",errno);
136  return(-1);
137  }
138 
139  if (verbose_flag)
140  {
141  fprintf(stderr,"\n\n Matrix Camera Control, Version 0.1\n\n");
142  fprintf(stderr," matrix rev %s\n",response);
144  len = read(qcr_data,response,BUFSIZ);
145  switch (response[0])
146  {
147  case 0x10: command = "M35"; break;
148  case 0x20: command = "M120"; break;
149  case 0x40: command = "M240"; break;
150  case 0xf0: command = "Empty"; break;
151  default: sprintf(command,"Unknown (%x) ",response[0]); break;
152  }
153  fprintf(stderr, "Camera back: %s\n", command);
154  }
155 }
156 
157 /*************************************************************************
158 
159  Print the current status of the QCR
160 
161 */
162 #define IS_ONE(resp_num, msg1, msg2) if (((int)response[resp_num + 1]) == 1)
163  printf(msg1); else printf(msg2);
165 {
166  int len, i, j;
167  unsigned char * rp;
168 
170  len = read( qcr_data, response, BUFSIZ );
171  printf("Got back %d status bytes\n", len);
172 
173  if (verbose_flag)
174  {
175  printf("Status data (in hex):\n");
176  rp = response;
177  for (j = 0; j < 2; j++)
178  {
179  for (i = 0; i < 16; i++)
180  printf("%2X ", (int) *rp++);
181  printf("\n");
182  }
183  }
184 
185  rp = response;
186  rp++; /* Output appears to have one junk byte... */
187 
188  IS_ONE(0, "External LUTs have been loaded for RGB\n",
189  "External LUTs have not been loaded for RGB\n");
190  IS_ONE(1, "External LUTs have been loaded for monochrome\n",
191  "External LUTs have not been loaded for monochrome\n");
192  printf("End of line time delay: %d\n", (int) rp[2]);
193  IS_ONE(4, "Automatic filter wheel operation is disabled\n",
194  "Automatic filter wheel operation is enabled\n");
195  IS_ONE(5, "Automatic camera operation is disabled\n",
196  "Automatic camera operation is enabled\n");
197 
198  printf("Start address (horiz, vert): %d, %d\n",
199  (int)(short)(((short)rp[12]) << 8) | rp[13],
200  (int)(short)(((short)rp[8]) << 8) | rp[9]);
201 
202  printf("Image dimensions (horiz, vert): %d, %d\n",
203  (((int) rp[10]) << 8) | rp[11],
204  (((int) rp[6]) << 8) | rp[7] );
205 
206  IS_ONE(15, "Automatic calibration enabled\n",
207  "Automatic calibration disabled\n");
208  IS_ONE(16, "End of image warble is disabled\n",
209  "End of image warble is enabled\n");
210  IS_ONE(17, "Black jumping is disabled\n",
211  "Black jumping is enabled\n");
212 
213  switch ((int)rp[18])
214  {
215  case 2:
216  printf("Resolution 2K\n");
217  break;
218  case 4:
219  printf("Resolution 4K\n");
220  break;
221  default:
222  printf("Weird resolution: %d\n", (int) rp[18]);
223  break;
224  }
225 
226  IS_ONE(19, "Mode externally selected\n",
227  "Mode is not externally selected\n");
228  IS_ONE(20, "90 degree rotation enabled\n",
229  "90 degree rotation disabled\n");
230  IS_ONE(21, "Mirror image enabled\n",
231  "Mirror image disabled\n");
232  IS_ONE(22, "Unbuffered raster mode enabled\n",
233  "Unbuffered raster mode disabled\n");
234  IS_ONE(23, "Return to no filter mode is disabled\n",
235  "Return to no filter mode is enabled\n");
236  IS_ONE(24, "Exchange of coords is selected\n",
237  "Exchange of coords is not selected\n");
238  IS_ONE(25, "Red-repeat is enabled\n",
239  "Red-repeat is disabled\n");
240  printf("Frame number: %d\n", (((int) rp[26]) << 8) | rp[27]);
241  IS_ONE(28, "Film is in camera\n",
242  "Film is not in camera\n");
243  IS_ONE(29, "Half frame mode enabled\n",
244  "Half frame mode disabled\n");
245  IS_ONE(30, "Bulk back in use\n", "" );
246  IS_ONE(31, "180 degree rotation enabled\n",
247  "180 degree rotation not enabled\n");
248 }
249 
250 /*************************************************************************
251 
252  Change the resolution, checking if it's OK first.
253 */
254 
256 int fourK;
257 {
258  int len;
259  char ch, *command;
260 
262  len = read(qcr_data,response,BUFSIZ);
263  fprintf(stderr," Current resolution mode: %x\n",response[18+1]);
264  if (len > 0)
265  { /* Use high-res (4K) (assume 4x5 back) */
266  if (fourK)
267  {
268  if ( response[18+1] != 4 ) /* +1 for extra junk byte */
269  {
271  if (verbose_flag)
272  printf("Resetting resolution to 4k, be patient.\n");
273  sleep(10); /* Yow! */
274  }
275  }
276  else /* We only need 2k */
277  if ( response[18+1] != 2 )
278  {
280  if (verbose_flag)
281  printf("Resetting resolution to 2k, be patient.\n");
282  sleep(10); /* Yow! */
283  }
284  }
285 }
286 
287 /*************************************************************************
288 
289  This code sets the location and size of the image on the film. Needs to
290  allow user specifications, as well as perhaps be a little smarter about
291  camera module defaults
292  Select the resolution, based on the dimensions x_size and y_size. At the
293  moment no provision for command-line placement of the image. This will
294  be added later, as soon as the basics are worked out. In most cases, 2K
295  will be used, so assume that as default. Check it anyway, to see if it
296  needs to be reset. This resolution selection should compare the current
297  film module defaults, rather than hardwiring x_size and y_size test values.
298  Also, try using ENABLE_2K and ENABLE_4K (63 and 64) commands, to avoid
299  the tedious resetting.
300 
301 */
302 
304 int x_size, y_size, nslice, offset;
305 {
306  int len;
307  char ch, *command;
308  short scan_start, row_start;
309  unsigned char sizes[8];
310  int res;
311 
312  if ((x_size > 2048) || (y_size > 1536))
313  set_resolution( 1 );
314  else
315  set_resolution( 0 );
316 
319  write_qcr_cmd(RED_REPEAT_ON); /* Let's see what happens */
320 
321  /* Now that the resolution is settled, center image on film */
322 
323  scan_start = (y_size >> 1 ) - offset;
324  row_start = 0 - (x_size >> 1 );
325 
326  if (verbose_flag)
327  fprintf(stderr,"-- centering %d x %d image, at (%d,%d)\n",
328  x_size,y_size,row_start,scan_start);
329 
330  sizes[0] = (char) (row_start >> 8) & 0xff;
331  sizes[1] = (char) row_start;
332 
333  sizes[2] = (char) (x_size >> 8) & 0xff;
334  sizes[3] = (char) x_size;
335 
336  sizes[4] = (char) (scan_start >> 8) & 0xff;
337  sizes[5] = (char) scan_start;
338 
339  sizes[6] = (char) (nslice >> 8) & 0xff;
340  sizes[7] = (char) nslice;
341 
343  write(qcr_data,sizes,8);
344 
345 }
346 
347 /***************************************************************************
348 
349  This is like "set_up_qcr", but does not center the image. It assumes
350  a coordinate range in the upper right quadrant (vs. the centered coords
351  the QCR really uses).
352 */
353 
354 set_up_qcr_nc( xstart, ystart, xsize, ysize, fourK )
355 {
356  unsigned char sizes[8];
357 
358  set_resolution( fourK );
359 
362  write_qcr_cmd(RED_REPEAT_ON); /* Let's see what happens */
363 
364  if (fourK)
365  {
366  xstart = xstart - (4096/2);
367  ystart = -ystart + (3072/2);
368  }
369  else
370  {
371  xstart = xstart - (2048/2);
372  ystart = -ystart + (1536/2);
373  }
374 
375  sizes[0] = (char) (xstart >> 8) & 0xff;
376  sizes[1] = (char) xstart & 0xff;
377 
378  sizes[2] = (char) (xsize >> 8) & 0xff;
379  sizes[3] = (char) xsize;
380 
381  sizes[4] = (char) (ystart >> 8) & 0xff;
382  sizes[5] = (char) ystart;
383 
384  sizes[6] = (char) (ysize >> 8) & 0xff;
385  sizes[7] = (char) ysize;
386 
388  write(qcr_data,sizes,8);
389 }
390 
391 /*
392  This routine makes some fatal assumptions, at least with our poor old 237
393  driving it. A maximum size pixel image, 4K square, would require three
394  buffers of 16 Megabytes each. Don't think that old 68010 box can handle
395  such data size. I'll have to check into this, see what the absolute limit
396  is. Perhaps a means of sending a row at a time, as it is processed rather
397  tha all at once?
398 
399  Anyway, this routine uses the burst mode, no handshaking.
400 
401 */
402 
404 int color,len;
405 char *buff;
406 {
407  char *cl;
408  int stat;
409 
410  switch(color) {
411  case RED:
412  cl = "Red";
414  break;
415  case GREEN:
416  cl = "Green";
418  break;
419  case BLUE:
420  cl = "Blue";
422  break;
423  default:
424  fprintf(stderr,"send_pixel_image: unknown color %d\n",color); break;
425  }
426 
427  if (verbose_flag)
428  fprintf(stderr,"send_pixel_image: %d bytes of %s... ",len,cl);
429  /* stat = write(qcr_data,buff,len); */
430  stat = write_data(buff,len);
432  if (verbose_flag)
433  {
434  if (stat > 0)
435  fprintf(stderr,"%d bytes sent.\n",stat);
436  else
437  fprintf(stderr," Error sending %s, errno = %d.\n",cl,errno);
438  }
439 
440  return (stat == len);
441 }
442 
444 int color,len;
445 char *buff;
446 {
447  char *cl;
448  int stat;
449 
450  switch(color) {
451  case RED:
452  cl = "Red";
454  break;
455  case GREEN:
456  cl = "Green";
458  break;
459  case BLUE:
460  cl = "Blue";
462  break;
463  default:
464  fprintf(stderr,"send_rle_image: unknown color %d\n",color); break;
465  }
466 
467  if (verbose_flag)
468  fprintf(stderr,"send_rle_image: %d bytes of %s... ",len,cl);
469  stat = write(qcr_data,buff,len);
471  if (verbose_flag)
472  {
473  if (stat > 0)
474  fprintf(stderr,"%d bytes sent.\n",stat);
475  else
476  fprintf(stderr," Error sending %s, errno = %d.\n",cl,errno);
477  }
478  return (stat == len);
479 }
480 
481 
482 /***************************************************************************
483 
484  Send a complete RLE encoded image in a single buffer.
485 
486 */
487 
488 int
490 unsigned char *buff;
491 int len;
492 {
493  int stat;
494 
496  if (verbose_flag)
497  fprintf(stderr,"send_3passrle_: %d bytes ... ",len);
498  write_data(buff,len);
499  /* stat = write(qcr_data,buff,len); */
500  if (verbose_flag)
501  {
502  if (stat > 0)
503  fprintf(stderr,"%d bytes sent.\n",stat);
504  else
505  fprintf(stderr," Error sending data, errno = %d.\n",errno);
506  }
507  return (stat == len);
508 }
509 
510 
511 /***************************************************************************
512 
513  Clean up after dumping the image. This should check for SRQ and error
514  conditions, perhaps reset the Matrix to a known state.
515 */
516 
518 {
519  close(qcr_cmd);
520  close(qcr_data);
521  close(qcr_raw);
522  }
523 
524 /***************************************************************************
525 
526  Attempt to reset the device, doesn't seem to always work yet.
527 
528 */
529 
530 int
532 {
533  fprintf(stderr," ** Reset QCR ** \n\n");
534  hpib_spoll(qcr_raw,3);
535  hpib_spoll(qcr_raw,2);
536  exit(-1);
537 }
538 
539 
541 char buf[];
542 {
544  if ( read( qcr_data, buf, BUFSIZ ) <= 0 )
545  {
546  perror( "Error reading brightness table\n" );
547  return 0;
548  }
549  return buf[0];
550 }
551 
552 
554 char buf[];
555 {
557  if ( read( qcr_data, buf, BUFSIZ ) <= 0 )
558  {
559  perror( "Error reading brightness levels\n" );
560  return 0;
561  }
562  return 1;
563 }
564 
566 unsigned char buf[1536];
567 {
569  write_data( buf, 3*256*2 );
570 }
571 
573 char buf[1536];
574 {
576  if ( read( qcr_data, buf, 1536 ) != 1536 )
577  {
578  perror( "Error reading 12 bit LUTs\n" );
579  return 0;
580  }
581  return 1;
582 }
583 
585 int lut;
586 {
587  char select_lut = lut;
589  write_data( &select_lut, 1 );
590  sleep( 2 );
591 }
qcr_wait_srq()
Definition: qcr.c:26
#define MODULE_ID
Definition: qcr.h:88
write_qcr_cmd(int cmd)
Definition: qcr.c:55
int init_qcr(short verbose)
Definition: qcr.c:104
#define THREE_PASS_RLE
Definition: qcr.h:32
unsigned char response[ 8192 ]
Definition: qcr.c:19
write_data(char *buff, int len)
Definition: qcr.c:74
#define IS_ONE(resp_num, msg1, msg2)
Definition: qcr.c:162
send_pixel_image(int color, char *buff, int len)
Definition: qcr.c:403
qcr_load_i_luts(int lut)
Definition: qcr.c:584
#define RED_RLE
Definition: qcr.h:43
#define VERIFY_12
Definition: qcr.h:23
#define GREEN_PIXEL
Definition: qcr.h:38
#define RETURN_BRIGHT_LEVELS
Definition: qcr.h:108
#define LOAD_12_LUT
Definition: qcr.h:22
#define GET_VERSION_ID
Definition: qcr.h:51
#define RETURN_BRIGHT_TABLE
Definition: qcr.h:111
short verbose_flag
Definition: qcr.c:17
#define RETURN_STATUS
Definition: qcr.h:116
#define SET_DIMENSIONS
Definition: qcr.h:53
int reset_qcr()
Definition: qcr.c:531
int qcr_raw
Definition: qcr.c:16
int send_3pass_rle(unsigned char *buff, int len)
Definition: qcr.c:489
int qcr_data
Definition: qcr.c:16
#define GREEN_RLE
Definition: qcr.h:44
#define IDLENGTH
Definition: qcr.h:52
#define LOAD_INTERN_LUT
Definition: qcr.h:78
print_qcr_status()
Definition: qcr.c:164
#define RED_PIXEL
Definition: qcr.h:37
qcr_rd_brt_tbl(buf)
Definition: qcr.c:540
#define RED_REPEAT_ON
Definition: qcr.h:61
close_qcr()
Definition: qcr.c:517
qcr_ld_lut12(buf)
Definition: qcr.c:565
send_rle_image(int color, char *buff, int len)
Definition: qcr.c:443
#define GREEN(x)
Definition: getami.c:50
set_up_qcr_nc(xstart, ystart, xsize, ysize, fourK)
Definition: qcr.c:354
qcr_rd_brt_lvl(buf)
Definition: qcr.c:553
#define RESOLUTION_2K
Definition: qcr.h:99
#define BLUE(x)
Definition: getami.c:51
#define BLUE_RLE
Definition: qcr.h:45
#define END_WARBLE_OFF
Definition: qcr.h:75
set_up_qcr(int x_size, int y_size, int nslice, int offset)
Definition: qcr.c:303
#define RESOLUTION_4K
Definition: qcr.h:100
#define RED(x)
Definition: getami.c:49
qcr_rd_lut12(buf)
Definition: qcr.c:572
#define BLUE_PIXEL
Definition: qcr.h:39
#define MIRROR_ENABLE
Definition: qcr.h:56
int qcr_cmd
Definition: qcr.c:16
int set_resolution(int fourK)
Definition: qcr.c:255