Driver for Dunn 635 color camera

karron at MCIRPS2.MED.NYU.EDU karron at MCIRPS2.MED.NYU.EDU
Sun Jul 22 09:23:00 AEST 1990


Here, as requested, is the source to my dunn camera driver. Do with it
as you will, but please, let me know what you do, or want the code to do.
I may want to do it too!

Please, if(when) you find bugs, or make improvements (there is lots of room
for that), send me your comments or mods to the source code.  I will be happy
to answer questions.  That is how I plan to document the program.  Run the
dunn -h with debug set on to get the inside documentation too.  There are lots
of stubs in the code for stuff I never finished.  The camera commands are
setup as compile time static data templates.  A better way might to have run
time construction of the dunn message blocks instead of compile time message
blocks.  For the moment, the code does what I need.

First, let me tell you about the code, and I will see if I can make
the source fit on the end of this letter. If you don't see my signature
at the end, let me know, and I will split up the source code. I don't know
if any of the machines on the way to you have a mail file size limitation
that may get in the way.

SYNOPSIS

dunn -[3b:cd:efg:him:p:rsx:zBSEX:HZ:]

A prototype program to drive the old LogE/Dunn 635 color camera via its rs232
serial port.  May work for other old dunn series cameras that use its CPM Z80
processor board.Despite its age, ours has worked properly (what is properly!)
without cpu problems for years.

The camera takes commands in fixed length message blocks with standard
headers, checksums, and, trailer characters.  You configure all of the serial
port and communications properties.  Make certain that they match what the
program expects.  There is an installers option in the program that show you
how to setup the camera from what the program expects.  I think that the
designers of the serial port never read the eia rs232 standard.  I have not
gotten the camera to properly handle RTS-CTS flow control.  My observations
with a breakout box indicate that they may reverse the meaning of DSR,DTR,and
DCD with RTS-CTS signal lines.  There are problems with character dropout when
running over 300 baud, which should have been fixed by using the sgi
/dev/ttym* ports (which use full handshaking including RTS-CTS).  For the
moment, I configure the camera rs232 port to disable CTS and DCD, and set the
baud rate at 300.  This is actually not so bad because the camera takes
soooooo long to cycle through the three filters on some films (polaroid 8032)
that the host does all of the waiting.  This is an area that should be fixed
in the future if someone wants to do more extensive work with the camera
(like myself, we have two here at the med ctr).  You will need to make a
special cable from the sgi plugs in the back of the conector.  From the
preceding, you can tell that the connections I have worked out don't seem to
do what I would expect.  My first expectation was that to get the two talking,
(both are DTE):

cross 2-3 (the numbering of the db9 and the db25 are the same except pin
20 on the db20 is pin 9 on the db9)
cross 4-5, and hold up 6(dsr)for the dunn.(I think)
cross DCD-DTR(9-20,8-9)

The above does NOT work as expected (RTS-CTS character level flow
control may actually be done by 8 and 20 (DCD-DTR) on the dunn, despite
what the documentation says and the diagnostics say. The diagnostic menu
includes a "screen" line that shows the status of the inbound flow
control lines. I could not get it to acknowledge what my breakout box
showed was actually happening at the connector.

Once the communications are worked out, you include the program dunn in
a shell script with lots and lots of arguments. My goal was to have an
argument for each camera command and parameters/argument list. This way
you can read the camera documentation in the appendex and run dunn -xxx
for each command.

Another feature, not really fully working is to exactly frame each
picture in a window sized to match the aspect ratio and size of the film.

I used the prefsize call to size the window, then a system call to
run the external program. You can calibrate the window with the program.
Once you have the right size window, it will write out and read a file
containing the window parameters. This also needs more work.

Since our camera has a 30 hz rate monitor, and our iris monitor is 60 hz,
you need to mess up the big monitor video with a 30hz gl call. Make certain
that you put things back when you exit, or you will have to log in on a
ascii terminal and reset the video.

For simple picture taking, dunn -B will take a big picture, dunn -E will take
an ektachrome 35 mmm. Look at the script movie.sh for an idea.

movie.sh----------CUT HERE-----CUT HERE----------CUT HERE-----CUT HERE----EOL
#! /bin/sh -xv
frames=$1
date
while [ $frames -gt 0 ]
do
dunn -d 1 -3 -E -r
echo "exposing $frames"
frames="`expr $frames - 1`"
done
dunn -d2 -z
date
exit 0
dunn.c---------CUT HERE-----CUT HERE----------CUT HERE-----CUT HERE----EOL
#include "stdio.h"
#include "gl.h"
#include "device.h"
#include "get.h"
#include "sys/termio.h"
#include "fcntl.h"
#include "string.h"
#include "getopts.h"

/* INSTALL OPTIONS  that YOU WILL WANT TO CHANGE */
/* make certain your camera settings match these below */
#define BAUD    B300
#define DEFAULT_SERIAL_PORT "/dev/ttyd2"
#define M1              'd'
#define M2              'b'
#define M3              'k'

/*
 * End of usual install options, rest you really don't want to change here.
 * You should change the camera settings to match these.
 */

#define CHECKSUM        '*'
#ifdef DEBUG
#define DEFAULT_DEBUG   0
#endif DEBUG
#define ACK_DISABLED    0
#define M4              CR
#define M5              LF /* leave this alone for canonical processing */
#define MESSAGE_SIZE    40

/* end of user configuration defines */
#define LONG_FILE_NAME     40
#define FILE_BUFFER_LENGTH 100
#define MESSAGE_WRAPPER_SIZE 13
#define MESSAGE_LENGTH  MESSAGE_SIZE-MESSAGE_WRAPPER_SIZE
#define READ_TIMEOUT    360 /* TENTHS SECONDS for non canonical read
                                                        does not mean any thing
for canonical reads */
#define MAX_RETRY       2
#define RETRY_SLEEP     10
#define CR              '\015'
#define LF                              '\012'
#define BLANK           ' '
#define B                               BLANK
#define BLANK10 BLANK,BLANK,BLANK,BLANK,BLANK,BLANK,BLANK,BLANK,BLANK,BLANK
#define PADDING BLANK10,BLANK10,BLANK10
#define LEAD_IN M1,M2,M3
#define BIGP808         1 /* big film */
#define BIGP809         3
#define BIGEKT64        5 /* little film */
#define BIGP891         7
#define BIGPLUSX        8
#define SMALLPLCRM      9
#define SMALLEKT64      10
#define COMMAND_STRING_SIZE MESSAGE_SIZE+1 /* pad with null for dbx */
#define RESET_TIME      5
#define FLUSH_IN_OUT    2
#define FLUSH_OUT       1
#define FLUSH_IN                0

/* camera message templates */

#define MAX_COMMANDS    10

#define RESET_CAMERA    0
#define MAKE_EXPOSURE   1
#define BEEP            2
#define DISPLAY_MESSAGE 3
#define CLEAR_MESSAGE   4
#define BIG_FILM        5
#define SMALL_FILM      6
#define CAMERA_STATUS   7
#define EXPOSURE_RESULTS 8
#define ERROR_STATUS     9
/* old style commands */
unsigned char make_exposure[COMMAND_STRING_SIZE] =
{LEAD_IN,'E','0','9',LF,B,B,PADDING,M5,NULL};

unsigned char beep[COMMAND_STRING_SIZE]=
{LEAD_IN,'S','P','0','1',M4,B,PADDING,M5,NULL};

unsigned char message_record[COMMAND_STRING_SIZE] =
{LEAD_IN,'S'  ,'M'  ,'0'  ,'2','x','x',PADDING,M5,NULL};

unsigned char unmessage[COMMAND_STRING_SIZE] =
{LEAD_IN,'S','M','0','0',M4,B,PADDING,M5,NULL};

unsigned char bigfilm[COMMAND_STRING_SIZE] =
{LEAD_IN,'S'  ,'B'  ,M4 ,B,B,B,PADDING,M5,NULL};

unsigned char smallfilm[COMMAND_STRING_SIZE] =
{LEAD_IN,'S'  ,'A'  ,M4 ,B,B,B,PADDING,M5,NULL};

unsigned char stat_req[COMMAND_STRING_SIZE] =
{LEAD_IN,'R'  ,'T'  ,M4 ,B,B,B,PADDING,M5,NULL};

unsigned char stat_exp[COMMAND_STRING_SIZE] =
{LEAD_IN,'R'  ,'E'  ,M4 ,B,B,B,PADDING,M5,NULL};
/* New style commands */
#define FILM            '0','0'
#define VIDEO_RED       '1'
#define VIDEO_GREEN     '2'
#define VIDEO_BLUE      '3'
#define VIDEO_CLEAR     '4'
#define VIDEO           VIDEO_RED
#define LEVEL_BLACK     '0','0','0'
#define LEVEL_WHITE     '1','1','1'
#define LVL_B
#define LVL_W
#define AUX_35mm        '1'
#define AUX_SX70        '2'
#define AUX_4x5         '3'
#define AUX_16mm        '4'
#define AUX_6x6         '5'
#define AUX_PR10        '6'
#define AUX_35mmCine    '7'
#define AUX             AUX_35mm
#define FILTER_HOME     '0'
#define FILTER_RED      '1'
#define FILTER_GREEN    '2'
#define FILTER_BLUE     '3'
#define FILTER_CLEAR    '4'
#define FILTER          FILTER_CLEAR
unsigned char command[MAX_COMMANDS][COMMAND_STRING_SIZE] =
                {
/* 0 */ {LEAD_IN , 'Z' ,  M4 ,  B  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL} ,
/* 1 */ {LEAD_IN , 'E' , '0' , '9' , LF  ,  B  ,  B  ,  PADDING , M5 , NULL} ,
/* 2 */ {LEAD_IN , 'S' , 'P' , '0' , '1' , M4  ,  B  ,  PADDING , M5 , NULL} ,
/* 3 */ {LEAD_IN , 'S' , 'M' , '0' , '2' , 'x' , 'x' ,  PADDING , M5 , NULL} ,
/* 4 */ {LEAD_IN , 'S' , 'M' , '0' , '0' , M4  ,  B  ,  PADDING , M5 , NULL} ,
/* 5 */ {LEAD_IN , 'S' , 'B' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL} ,
/* 6 */ {LEAD_IN , 'S' , 'A' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL} ,
/* 7 */ {LEAD_IN , 'R' , 'T' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL} ,
/* 8 */ {LEAD_IN , 'R' , 'E' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL} ,
/* 9 */ {LEAD_IN , 'R' , 'T' , 'E' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}
#ifndef FULL_COMMAND_LIST
                };
#endif

#ifdef FULL_COMMAND_LIST
/*10 */ {LEAD_IN , 'A' ,   FILM    ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    autocomp FILM */
/*11 */ {LEAD_IN , 'B' ,   FILM    ,VIDEO,  M4 ,  B  ,  PADDING , M5 , NULL}, /*
    set b/w for FILM */
/*12 */ {LEAD_IN , 'C' ,   FILM    , AUX ,  M4 ,  B  ,  PADDING , M5 , NULL}, /*
    set aux FILM */
/*13 */ {LEAD_IN , 'C' , 'F' ,  M4 ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    copy */
/*14 */ {LEAD_IN , 'D' ,   FILM    ,VIDEO,  M4 ,  B  ,  PADDING , M5 , NULL}, /*
    set bright/contrast */
/*15 */ {LEAD_IN , 'E' ,   FILM    ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    expose */
/*16 */ {LEAD_IN , 'E' , 'A' , FILM      ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    expose adjust */
/*17 */ {LEAD_IN , 'E' , 'B' , FILM      ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    expose adjust color */
/*18 */ {LEAD_IN , 'E' , 'C' , FILM      ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    expose contaminant */
/*19 */ {LEAD_IN , 'E' , 'F' , FILM,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    expose stuff */
/*20 */ {LEAD_IN , 'F' ,FILTE,  M4 ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    move filter */
/*21 */ {LEAD_IN , 'F' , 'C' , FILM      ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    set frame counter */
/*22 */ {LEAD_IN , 'K' ,KYBRD, M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    keyboard disable */
/*23 */ {LEAD_IN , 'M' ,BLANK,  B' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    monitor blanking */
/*24 */ {LEAD_IN , 'N' , 'T' ,  B  ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    set film name */
/*25 */ {LEAD_IN , 'P' , 'T' ,  B  ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    image polarity */
/*26 */ {LEAD_IN , 'Q' ,  B  ,  B  ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    raster blend setting */
/*27 */ {LEAD_IN , 'R' , 'A' ,  M4 ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    request autocomp */
/*28 */ {LEAD_IN , 'R' , 'B' , FILM,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    request b/w level */
/*29 */ {LEAD_IN , 'R' , 'C' , 'E' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    request camera type */
/*30 */ {LEAD_IN , 'R' , 'D' , 'E' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    request bright/contrast */
/*31 */ {LEAD_IN , 'R' , 'E' , 'E' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL},
/*32 */ {LEAD_IN , 'R' , 'E' , 'F' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL},
/*33 */ {LEAD_IN , 'R' , 'E' , 'C' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL},
/*34 */ {LEAD_IN , 'R' , 'N' , 'E' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL},
/*35 */ {LEAD_IN , 'R' , 'P' , 'E' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL},
/*36 */ {LEAD_IN , 'R' , 'Q' , 'E' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL},
/*37 */ {LEAD_IN , 'R' , 'S' , 'F' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL},
/*38 */ {LEAD_IN , 'R' , 'T' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL},
/*39 */ {LEAD_IN , 'R' , 'T' , 'E' ,  M4 ,  B  ,  B  ,  PADDING , M5 , NULL},
/*40 */ {LEAD_IN , 'S' , 'A' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL},
/*41 */ {LEAD_IN , 'S' , 'B' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL},
/*42 */ {LEAD_IN , 'S' , 'C' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL},
/*43 */ {LEAD_IN , 'S' , 'D' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL},
/*44 */ {LEAD_IN , 'S' , 'E' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    select separate */
/*45 */ {LEAD_IN , 'S' , 'F' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    select separate w/o advance */
/*46 */ {LEAD_IN , 'S' , 'K' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    select film type */
/*47 */ {LEAD_IN , 'S' , 'M' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    turn speaker on */
/*48 */ {LEAD_IN , 'S' , 'P' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    send message */
/*49 */ {LEAD_IN , 'S' , 'V' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    beep speaker */
/*50 */ {LEAD_IN , 'X' , 'C' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    select video channel */
/*51 */ {LEAD_IN , 'X' , 'E' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    close aux shutter */
/*52 */ {LEAD_IN , 'X' , 'D' , M4  ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    eject aux film */
/*53 */ {LEAD_IN , 'Z' , M4  , B   ,  B  ,  B  ,  B  ,  PADDING , M5 , NULL}, /*
    open aux shutter */
                };
#endif FULL_COMMAND_LIST
/* acknowledge codes from camers */

#define ACK0 "Message Received Okay."
#define ACK1 "Parity Error."
#define ACK2 "Framing Error."
#define ACK3 "Overrun Error."
#define ACK4 "Message Too Long."
#define ACK5 "Message Too Short."
#define ACK6 "Checksum Error."
#define ACK7 "Bad Message Format. M3 character not in third char of message \
block."

/* condition your serial port this way */
struct termio new_state=        {
/* new_state.c_iflag= */    IGNBRK|IGNPAR ,
/* new_state.c_oflag= */    NULL ,
/* new_state.c_cflag= */    BAUD|CS8|CREAD|CLOCAL ,
/* new_state.c_line=  */    ICANON ,
/* new_state.c_cc[VINTR]= */NULL ,
/* new_state.c_cc[VQUIT]= */NULL ,
/* new_state.c_cc[VERASE]=*/NULL ,
/* new_state.c_cc[VKILL]= */NULL ,
/* new_state.c_cc[VMIN]=  */NULL , /* does not mean anything in with ICANON set
   */
/* new_state.c_cc[VTIME]= */NULL /* does not mean anything in with ICANON set */
                                                        };

void initport();
void beepit();
void scram();
void xmit_command();
void make_message();
void mess();
void unmess();
void expose();
void PrintHelpAndExit();
void ResetCamera();
void ReportCommand();
void SizeWindowFrame();
void NumericError();
void AnalyzeError(char *,int, int , int , char *, char *, char *, int, int);

int TotalRetrys=0;
static char path[]=DEFAULT_SERIAL_PORT;
int fd;
int noack=ACK_DISABLED;
#ifdef DEBUG
int debug=DEFAULT_DEBUG;
#endif DEBUG
int flush=0;
int reset=0;
int InWindow=1;
int NoBorder=0;
int FilmNumber = -1;
#define MAX_WINDOWS 3
struct WindowTag {
    long wid;
    long wxsize;
    long wysize;
    long xorg;
    long yorg;
    } Window[MAX_WINDOWS];



/***************************************************************\
|=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=|
\***************************************************************/
void
main(int argc, char **argval)
{
static char options[]="3b:cd:efg:him:p:rsx:zBSEX:HZ:";
static char FrameWindowFile[LONG_FILE_NAME]=NULL;

char DisplayMessage[MESSAGE_LENGTH];

int film_spec,beeps,c=0;
int ReportCameraStatus=0;
int ReportExposureResults=0;
int ReportErrorStatus=0;
int Hz30=0;
int PreviewTime=0;
int FrameWindow=0;
int CommandNumber= -1;

if (argc==1)
        PrintHelpAndExit(*argval,options);

#ifdef DEBUG
if (getenv("DEBUG"))
        sscanf(getenv("DEBUG"),"%d",&debug);
#endif DEBUG

if(getenv("CAMERA_PORT"))
        sscanf(getenv("CAMERA_PORT"),"%s",path);

while((c=getopt(argc,argval,options)) != -1)
        switch (c)
        {
        case '3':
        Hz30=1;
        break;

        case 'b':
        sscanf(optarg,"%d",&beeps);
        break;

        case 'c':
        NoBorder=1;
        break;

#ifdef DEBUG
        case 'd':
        sscanf(optarg,"%d",&debug);
        printf("debug set to %d\n",debug);
        break;
#endif DEBUG

        case 'e':
        ReportErrorStatus=1;
        break;

        case 'f':
        flush=1;
        break;

        case 'g':
        sprintf(FrameWindowFile,"%s",optarg);
        case 'i':
        FrameWindow=1;
        break;

        case 'm':
        sprintf(DisplayMessage,"%s",optarg);
        break;

        case 'p':
        sscanf(optarg,"%s",path);
        break;

        case 'r':
        ReportExposureResults=1;
        break;

        case 's':
        ReportCameraStatus=1;
        break;

        case 'x':
        sscanf(optarg,"%d",&noack);
        break;

        case 'z':
        reset=1;
        break;

        case 'B':
        film_spec=BIGP809;
        break;

        case 'E':
        film_spec=SMALLEKT64;
        break;

        case 'F':
        if(!sscanf(optarg,"%d",&FilmNumber))
            NumericError(c,optarg,*argval,options);
        break;

        case 'S':
        film_spec=SMALLPLCRM;
        break;

        case 'X':
        if(!sscanf(optarg,"%d",&CommandNumber))
            NumericError(c,optarg,*argval,options);
        break;

        case 'Z':
        sscanf(optarg,"%d",&PreviewTime);
        break;

        case '?':
        case 'H':
        case 'h':
        default:
        PrintHelpAndExit(*argval,options);
        }

initport();
if (reset)ResetCamera();
if (beeps)beepit(beeps);
if (Hz30)mess();
if (strlen(DisplayMessage))make_message(DisplayMessage);
if (FrameWindow)SizeWindowFrame(FrameWindowFile);
if (PreviewTime)sleep(PreviewTime);
if (film_spec)expose(film_spec);
if ( CommandNumber>-1 && CommandNumber < MAX_COMMANDS)
        xmit_command(command[CommandNumber]);
if (ReportCameraStatus)ReportCommand(command[CAMERA_STATUS]);
if (ReportErrorStatus)ReportCommand(command[ERROR_STATUS]);
if (ReportExposureResults)ReportCommand(command[EXPOSURE_RESULTS]);
if (Hz30)unmess();
scram(*argval);
exit(0);
}
/********************************************************************/

void
initport()
{
#ifdef DEBUG
if (debug>1)
    {
    printf("Setting port %s\n",path);
    }
#endif
if((fd=open(path,O_RDWR)) <0)
        {
        fprintf(stderr,"Unable to open %s\n",path);
        perror("unable to open file");
        exit(1);
        }

ioctl(fd,TCSETA,&new_state);
return;
}
/****************************************************************************/

void
scram(char *ProgName)
{
if(flush)ioctl(fd,TCFLSH,FLUSH_IN_OUT);
close(fd);
#ifdef DEBUG
if (debug)
    printf("total retrys is %d\n",TotalRetrys);
if (debug>1)
    printf("%s completed\n",ProgName);

#endif
return;
}
/****************************************************************************/
void
xmit_command(command)
char *command;
{
char line_buffer[MESSAGE_SIZE];
int retry=0;
int written=0;
int red=0;

do      {
        written=write(fd,command,MESSAGE_SIZE);
        if(flush)ioctl(fd,TCFLSH,FLUSH_OUT);
        if(noack)
                {
                sleep(noack);
                return;
                }
        red=read(fd,line_buffer,MESSAGE_SIZE);

        if(
           ( line_buffer[0] != command[0] ) ||
           ( line_buffer[1] != command[1] ) ||
           ( line_buffer[2] != command[2] ) ||
           ( line_buffer[3] != '0'        ) )
                {
#ifdef DEBUG
                if(debug)AnalyzeError("xmit_command ERROR",written,
                        red,retry,command,line_buffer,__FILE__,__LINE__,debug);
#endif DEBUG
        TotalRetrys += (++retry);
                sleep(RETRY_SLEEP);
                } /* data read error */
#ifdef DEBUG
                else
                {
                if(debug>1)AnalyzeError("xmit_command OK",written,
                        red,retry,command,line_buffer,__FILE__,__LINE__,debug);
                }
#endif DEBUG
        } while (retry > 0 && retry < MAX_RETRY);
return;
}
/********************************************************************/
void
ReportCommand(command)
char *command;
{
char line_buffer[MESSAGE_SIZE];
int retry=0;
int written=0;
int red=0;

do      {
        written=write(fd,command,MESSAGE_SIZE);
        if(flush)ioctl(fd,TCFLSH,FLUSH_OUT);
        red=read(fd,line_buffer,MESSAGE_SIZE);

        if (
           ( line_buffer[0] != command[0] ) ||
           ( line_buffer[1] != command[1] ) ||
           ( line_buffer[2] != command[2] ) ||
               ( line_buffer[3] != '0'        ) )
                {
#ifdef DEBUG
                if(debug)AnalyzeError("ReportCommand ERROR",written,
                        red,retry,command,line_buffer,__FILE__,__LINE__,debug);
#endif DEBUG
        TotalRetrys += (++retry);
                sleep(RETRY_SLEEP);
                } /* data read error */
#ifdef DEBUG
                else
                {
                if(debug>1)AnalyzeError("ReportCommand OK",written,
                        red,retry,command,line_buffer,__FILE__,__LINE__,debug);
                }
#endif DEBUG
        } while (retry > 0 && retry < MAX_RETRY);
printf("status:%c %c\n",line_buffer[4],line_buffer[5]);
return;
}
/********************************************************************/

void
make_message(message)
char message[];
{
unsigned int message_length = strlen(message);
register int i;
unsigned char thingstring[2];

if (message_length > MESSAGE_LENGTH)
        {
#ifdef DEBUG
        if(debug)
                {
                printf("message '%s' too long at %d characters\n",
                        message,message_length);
                printf("at this time, the maximum message is %d\n",MESSAGE_SIZE-
13);
                }
#endif DEBUG
        message_length=MESSAGE_SIZE-13;
        }
/* do this better... come on!! */
sprintf(thingstring,"%02u",message_length);
printf("thingstring=%s... any blanks ?\n",thingstring);
message_record[5]=thingstring[0];
message_record[6]=thingstring[1];

for(i=0;i<message_length;i++)message_record[7+i]=message[i];
message_record[7+i]=M4;
xmit_command(message_record);
return;
}
/*********************************************************************/

void
mess()
{
    if(InWindow)
    {
    noport();
    foreground();
    winopen();
    InWindow=0;
    }
#ifdef DEBUG
if (debug>1)
    {
    printf("setmonitor(HZ30);\n");
    }
#endif
setmonitor(HZ30);
return;
}
/***********************************************************************/
void
unmess()
{
if(InWindow)
    {
    noport();
    foreground();
    winopen();
    InWindow=0;
    }
#ifdef DEBUG
if (debug>1)
    {
    printf("setmonitor(HZ60);\n");
    }
#endif
setmonitor(HZ60);
return;
}
/*************************************************************************/

void
expose(int film_type)
{
if((film_type < 1) || (film_type > 24))
        {
        printf("bad film type : %d ",film_type);
        return;
        }

if(film_type <= 8)xmit_command(bigfilm);
             else xmit_command(smallfilm);

sprintf(&make_exposure[4],"%02d",film_type);
if(make_exposure[4] == BLANK)make_exposure[4]='0';
if(make_exposure[5] == BLANK)make_exposure[5]='0';
make_exposure[6]=M4;

xmit_command(make_exposure);
return;
}
/************************************************************************/
void
beepit(int number_of_times)
{

sprintf(&command[BEEP][5],"%02d",number_of_times);
if(command[BEEP][5] == BLANK)command[BEEP][5]='0';
if(command[BEEP][6] == BLANK)command[BEEP][6]='0';
command[BEEP][7]=M4;
xmit_command(command[BEEP]);
return;
}
/***********************************************************************/
void
ResetCamera()
{
xmit_command(command[RESET_CAMERA]);
sleep(RESET_TIME);
exit(0);
return;
}
/***********************************************************************/
void
PrintHelpAndExit(char *ProgName,char *Options)
{
printf("%s :=<%s> makes exposures on DUNN 635 color camera\n",ProgName,Options);
printf("'-B' for 8x10 polaroid color\n");
printf("'-S' for 35 mm polaroid polapan\n");
printf("'-E' for 35 mm Ektachrome\n");
printf("'-p:</dev/serial_port> rs232 port to camers\n");
printf("     or set CAMERA_PORT in environment\n");
printf("'-3' Change refresh to 30 Hertz for dunn camera,mess up screen\n");
printf("'-Z' sleep time to preview messed up screen\n");
#ifdef DEBUG
printf("'-d:<value,0-2> runtime debug\n");
printf("   1=report bad acks from camers\n");
printf("   2=report all transactions with camers\n");
printf("       with -[h|H] option will report installer info\n");
#endif DEBUG
printf("'-z' reset/reboot camera. Will exit prog.\n");
printf("'-i' size window frame and printf scoords to stdout.\n");
printf("'-g <filename>' read window size from file,\n");
printf("      and write new scoords to same file.\n");
printf("'-r' report exposure results,\n");
printf("      will block until exposure is completed.\n");
#ifdef DEBUG
if (debug)
        {
        printf("\n");
#ifdef ANSI
        printf("COMPILED on %s %s\n",__DATE__,__TIME__);
#endif
        printf("DETAILED INFO FOR INSTALLERS\n");
        printf("MAKE CERTAIN THAT THE CAMERA SETTINGS AGREE WITH THESE SETTINGS
\n");
        printf("ACKNOWLEDGE_ENABLED\n");
        printf("MESSAGE_SIZE=%d\n",MESSAGE_SIZE);
        printf("LEAD IN CHARACTERS in dec,oct,hex,char\n");
        printf("M1=%d,%o,%x,%c\n",M1,M1,M1,M1);
        printf("M2=%d,%o,%x,%c\n",M2,M2,M2,M2);
        printf("M3=%d,%o,%x,%c\n",M3,M3,M3,M3);
        printf("M4=%d,%o,%x,%c\n",M4,M4,M4,M4);
        printf("M5=%d,%o,%x,c\n",M5,M5,M5,M5);
        printf("LEAD_IN=%c%c%c\n",LEAD_IN);
        printf("COMMUNICATIONS SETTINGS IN CAMMERA MUST AGGREE WITH ioctl SETTIN
GS\n");
        printf("BAUD=%d\n",BAUD);
        printf("SERIAL PORT=%s\n",path);
        }
#endif DEBUG
exit(1);
}
/***********************************************************************/
#ifdef DEBUG
#define PutAllAscii(s) \
{\
register int i;\
for (i=0;s[i]!=NULL;i++)\
    {\
        if (s[i] < ' ')\
        {\
            switch(s[i])\
            {\
            case CR: \
            putchar('\\');\
            putchar('r');\
            break;\
            \
            case LF: \
            putchar('\\');\
            putchar('n');\
            break;\
            \
            default: \
            putchar('^');\
            putchar(s[i]+' '/2);\
            }\
        }\
    else\
        putchar(s[i]);\
    }\
}

void
AnalyzeError(message, Writ, Red, ReTry, Command,
                         LineBuffer,File,Line,DebugLevel)
char *message;
int Writ;
int Red;
int ReTry;
char *Command;
char *LineBuffer;
char *File;
int Line;
int DebugLevel;
{
printf("\nAnalyzeError called from (debug=%d)%s:%d:%s\n",
                        DebugLevel,File,Line,message);
printf("MESSAGE_SIZE=%d\t",MESSAGE_SIZE);
printf("writ=%d,Red=%d\n",Writ,Red);
printf("ReTrys=%d,Total Retrys=%d\n",ReTry,TotalRetrys);
printf("SENT:\t<");
PutAllAscii(Command);
printf(">\n");

printf("GOT:\t<");
PutAllAscii(LineBuffer);
printf(">\n");


printf("M1(%c==%c)\t",      LineBuffer[1],Command[1]);
printf("M2(%c==%c)\t",      LineBuffer[0],Command[0]);
printf("M3(%c==%c)\t",      LineBuffer[2],Command[2]);
printf("ACK:(%c==%c)\n",    LineBuffer[3],'0');
switch (LineBuffer[3])
        {
        case '0':
        printf("Acknowledgement GOOD\n");
        break;

        case '1':
        printf("Ack err:%s\n", ACK1);
        break;

        case '2':
        printf("Ack err:%s\n", ACK2);
        break;

        case '4':
        printf("Ack err:%s\n", ACK4);
        break;

        case '5':
        printf("Ack err:%s\n", ACK5);
        break;

        case '6':
        printf("Ack err:%s\n", ACK6);
        break;

        case '7':
        printf("Ack err:%s\n", ACK7);
        break;

        default:
        printf("Ack unknown error\n");
        break;

        } /* switch */
printf("\n");
return;
}
#endif DEBUG
/***************************************************************\
|=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=|
\***************************************************************/

void
SizeWindowFrame(FileName)
char *FileName;
{
int i;
int MaxWindows=1;
char LineBuffer[FILE_BUFFER_LENGTH];
char title[80];
int PreferenceReadIn=0;
short qval,qred;
FILE *WindowFile=stdin;

if (*FileName)
    {
    if(NULL==(WindowFile=fopen(FileName,"r")))
        {
        fprintf(stderr,"Can't open file %s\n",FileName);
        perror("SizeWindow");
        return;
        }

        for (i=0;
        (fgets(LineBuffer,FILE_BUFFER_LENGTH,WindowFile))&&(i<MAX_WINDOWS);
        MaxWindows = ++i)
        {
        if(4!=sscanf(LineBuffer,"%ld,%ld,%ld,%ld\n",
                    &Window[i].xorg,
                    &Window[i].yorg,
                    &Window[i].wxsize,
                    &Window[i].wysize))
                        printf("Scan error on %s\n",LineBuffer);
        fclose(WindowFile);
        link(FileName,".bWINDOW");
        unlink(FileName);
        PreferenceReadIn=1;
        }
    }

i=0;
    do {
    foreground();
    sprintf(title,"%s:Win[%d]=%ld",FileName,i,Window[i].wid);
    if (NoBorder)
        noborder();
    if(PreferenceReadIn)prefposition(Window[i].xorg,
        Window[i].xorg+Window[i].wxsize,
        Window[i].yorg,
        Window[i].yorg+Window[i].wysize);
    Window[i].wid=winopen(title);
    InWindow=0;
    sprintf(title,"%s:Win[%d]=%ld",FileName,i,Window[i].wid);
    wintitle(title);
    winconstraints();
    qdevice(RIGHTMOUSE);
    qdevice(MIDDLEMOUSE);
    qdevice(LEFTMOUSE);
    qdevice(INPUTCHANGE);
    qdevice(REDRAW);
    while(qred=qread(&qval))
    switch (qred)
    {
    case RIGHTMOUSE:
    color(WHITE);
    clear();
    getsize(&Window[i].wxsize, &Window[i].wysize);
    getorigin(&Window[i].xorg,&Window[i].yorg);
    goto scram;
    break;

    default:
    color((int)qval);
    clear();
    getsize(&Window[i].wxsize, &Window[i].wysize);
    getorigin(&Window[i].xorg,&Window[i].yorg);
    break;
    }
scram:;
    }while((++i<MaxWindows)&&(i<MAX_WINDOWS));


if (*FileName)
    {
    if(NULL==(WindowFile=fopen(FileName,"w")))
        {
        fprintf(stderr,"Can't open file %s\n",FileName);
        perror("SizeWindow");
        return;
        }
    }

for(i=0;i<MaxWindows;i++)
    {
    if (*FileName)
        {

        fprintf(WindowFile,"%ld,%ld,%ld,%ld\n",
                Window[i].xorg,
                Window[i].yorg,
                Window[i].wxsize,
                Window[i].wysize);
        } else
        {
        printf("%ld,%ld,%ld,%ld\n",
                Window[i].xorg,
                Window[i].yorg,
                Window[i].wxsize,
                Window[i].wysize);
        }
    }

fflush(WindowFile);
if (*FileName)
    {
    fclose(WindowFile);
    }
return;
}
/**************************************************************/
void
NumericError(OptionLetter,OptionArgument,a,o)
char OptionArgument,*OptionLetter,*a,*o;
{
fprintf(stderr,"Unable to scan numeric argument -%c,%s\n",
    OptionLetter,OptionArgument);
PrintHelpAndExit(a,o);
}
/*********************/

-END OF dunn.c-------------------
--
+-----------------------------------------------------------------------------+
| karron at nyu.edu                          Dan Karron                          |
| . . . . . . . . . . . . . .             New York University Medical Center  |
| 560 First Avenue           \ \    Pager <1> (212) 397 9330                  |
| New York, New York 10016    \**\        <2> 10896   <3> <your-number-here>  |
| (212) 340 5210               \**\__________________________________________ |
+-----------------------------------------------------------------------------+



More information about the Comp.sys.sgi mailing list