Title: SPECIFICATION FOR LIGO BAKEOUT SYSTEMSOFTWARE
TEMPERATURE AQUISITION
SPECIFICATION FOR
LIGO BAKEOUT SYSTEM SOFTWARE
TEMPERATURE AQUISITION
FOR
LIGO VACUUM EQUIPMENT
Hanford, Washington
and
Livingston, Louisiana
PREPARED BY:
ELECTRICAL:
QUALITY ASSURANCE:
TECHNICAL DIRECTOR:
PROJECT MANAGER:
0 BAR 5/9/96 ISSUED FOR RELEASE PER DEO 0182
TABLE OF CONTENTS
PROGRAM DESCRIPTION, TEMP ...... PAGE 3
PROGRAM DESCRIPTION, MONITOR ...... PAGE 5
PROGRAM DESCRIPTION, STARTUP ...... PAGE 6
SOURCE CODE, TEMP.C ...... PAGE 7
SOURCE CODE, MONITOR.C ...... PAGE 27
Program: TEMP
Description:
The TEMP program is the main interface between the Tempscan temperature data logger
and the Allen Bradley PLC5 processor.
Operation:
The program reads the temperature values from the Tempscan temperature data logger. For
normal operation, 192 values are read, if the optional expansion card is used, then 224 values will
be read.
The values are first read in from the Tempscan in groups of 4. The small grouping is primarily
due to the small (128 byte) input buffer. Each value is then rounded off to the nearest integer and
checked against the allowable ranges read in from the PLC. Value designations are setup as follows:
Thermouple “A” values are odd Tempscan T/C numbers, “B” values are even. These values are then
written to specific registers in the PLC.
Error indications written to PLC:
Temperature errors:
Thermocouple “A” value out of range, bit 0x0001 set.
Thermocouple “B” value out of range, bit 0x0002 set.
Communication errors:
Communication heartbeat, set each read/write cycle, bit 0x0001 set.
Communication to Tempscan timeout, bit 0x0002 set.
Tempscan error, bit 0x0004 set.
Program operation errors:
Id number refering to the location in the program where the error occurred, and the error number
as reported by the Coprocessor. Note that errors involving registor identification and PLC set-up
will cause termination of the program. If this occurs, the heartbeat bit will no longer be set and
the PLC5 program will trap this condition.
Error Recovery:
If communications to the tempscan unit is lost (a timeout error has occured), the communications
cycle loop timer will default to a value of three. This causes the program to constantly poll the Tempscan
unit untill communications are restored. When communications are restored, this value will revert to its
original value. During this communications loss, only error values will be written to the plc unit, temperature values will NOT be passed to the plc. However, as the plc will report an error condition when the loop timer
times out, this will not pose a problem. The heartbeat bit will not be set so that the plc unit will report the
timeout conditions when the loop timer times out.
If communications are restored before the plc reports an error condition, the Tempscan unit will reset,
purge the I/O buffers and begin passing values to the temp program. The Tempscan unit has a minimum
reset time of about 4 seconds.
If communications problems develop between the the plc and co-processor module, the plc will have
the onus of detecting them and warning the operator. The co-processor is completely dependant upon the
plc system for internal communications.
Program options:
There are 2 command line options that can be used with the program, “exp” and “dbg”.
Using “exp” will cause the program to assume that an additional card has been added to the expansion
base for a total of 224 thermocouple values.
Using “dbg” will cause the program to print out function names as a troubleshooting assist. When using
this option, do not run the program as a background process. Refer to the startup script file description.
The two options are not position dependent and may be used together.
Examples:
&temp exp&
(run as background process with expansion)
temp dbg exp
(run as foreground process with expansion & debug printing on)
Interprocess communications:
The program sets up a new entry into the 0S9 event table called monitor. After all of the information has
been sent to the PLC5, and a text file containing this information has been written, the event is set to a value
of 255 (0xFF). This signals the monitor program to open and read the information in the tempdata file.
Refer to the monitor program description.
Program: MONITOR
NOTE: A COMPUTER MUST BE ATTACHED TO THE COMM0 PORT OF THE COPROCESSOR
AND BE RUNNING THE ALLEN BRADLEY PCBRIDGE SOFTWARE.
Description:
The MONITOR program provides a means to view the temperature values and the error information
being passed to the PLC5 by the TEMP program. This program is dependent on the TEMP program
operating.
Operation:
This program reads in the tempdata file created by the TEMP program. This program is triggered
by the monitor event added to the event table by the TEMP program being set to 255 (0xFF). When
this occurs, the program reads in the tempdata file created by the TEMP program, and displays it
on the monitor. One group of 32 temperature zones are displayed at one time due to space considerations, but
by using the ctrl-c key combination, the group number can be looped from one to seven (32 values per group).
On startup, the top line of the screen will display “Waiting for trigger event”. This will remain untill the
trigger is set from the TEMP program.
Program options:
If desired, the operator may include a temperature group number on the command line. If this is not included,
the program starts up displaying zones number 1A/1B thru 16A/16B. This program should be run as a foreground process.
Example:
monitor 2
(displays zones number 17A/17B thru 32A/32B when it starts up)
Program: STARTUP
Description:
The startup file is a text procedure file that executes on when the system boots up. Its primary
purpose is to set up the communications parameters and start the TEMP program running properly.
*
* procedure startup file
*
setime -s ;* set the system time from battery-backed clock
deiniz /t1 ;* remove port /t1 from system (this is comm1)
xmode /t1 baud=9600 ;* set up new parameters for /t1
xmode /t1 par=none ;* no parity
xmode /t1 cs=8 ;* 8 data bits
xmode /t1 stop=1 ;* 1 stop bits
xmode /t1 xon=0 ;* xon & xoff = 0 forces
xmode /t1 xoff=0 ;* RTS/CTS hand-shaking
iniz /t1 ;* attach port with new parameters to system
&temp& ;* the first "&" denotes concurrent background execution
* the second "&" returns to the shell process
PAGE 1 OF 34
Title: SPECIFICATION FOR LIGO BAKEOUT SYSTEMSOFTWARE
TEMPERATURE AQUISITION
/*********************************************************************/
/* temp.c Temperature retrieval and processing software */
/* */
/* Customer: Ligo */
/* */
/* Author: Bruce A. Roth */
/* Date: 04/30/96 */
/* Version: 1.00 */
/* */
/* Target system: A-B Control Coprocessor */
/* Cat. No...: 1771-DMC */
/* Part No...: 96904482 */
/* Series....: A */
/* Revision..: Q01 */
/* Serial No.: ST0IZ6HV */
/* */
/* Usage: &temp [exp] [dbg]& */
/* exp: Adds code for expansion heater zones */
/* number 77 thru 92. */
/* dbg: Enable printing of debug information */
/* to the local terminal. */
/* These may be placed in the command line */
/* in any order. */
/* */
/* */
/*********************************************************************/
#include <stdio.h>
#include <math.h>
#include <strings.h>
#include <sgstat.h>
#include <copro.h>
#include <modes.h>
#include <errno.h>
#include <time.h>
#include <ctype.h>
#include <events.h>
/************************/
/* CONSTANT DEFINITIONS */
/************************/
/* Roundoff is a string to integer in-line function. Used by the get_val function*/
#define roundoff(s) atof(s)>0 ? (int)(atof(s)+0.5) : (int)(atof(s)-0.5)
#define TRUE 1
#define FALSE 0
#define CLR() printf("\33[2J") /* clears the screen */
#define MOVE(x,y) printf("\33[%d;%dH",y,x) /* moves the cursor to x,y */
/*******************************/
/* GLOBAL VARIABLE DEFINITIONS */
/*******************************/
unsigned int tc_a_id; /* t/c "A" values plc register identification handle */
unsigned int tc_b_id; /* t/c "B" values plc register identification handle */
unsigned int tc_err_id; /* t/c "A" & "B" out of range plc register identification handle */
unsigned int tc_setpt_id; /* t/c setpoint plc register identification handle */
unsigned int loop_time_id; /* loop time setpoint plc register identification handle */
unsigned int comm_err_id; /* Communication errors, heartbeat plc register identification handle */
unsigned int copro_err_id; /* Coprocessor error plc register identification handle */
int tcval_a[112]; /* Thermocouple "A" values */
int tcval_b[112]; /* Thermocouple "B" values */
unsigned int tc_err[112]; /* Thermocouple "A" & "B" out of range errors */
int tc_setpt[8]; /* Thermocouple range setpoints */
int loop_time[2]; /* Program control loop time setpoint */
unsigned int comm_err; /* Communication errors, heartbeat */
unsigned int copro_err[2]; /* Coprocessor errors, program ID & error number */
unsigned int iostat_err; /* IO status error number */
int DEBUG=0; /* debugging off or on */
int EXP=0; /* expansion heaters #77 thru 92 enabled */
int path; /* Path to communications device */
FILE *fpath; /* file pointer for troubleshooting data file */
int ev_id; /* event id to signal monitoring program */
char temp_err[5]; /* reported tempscan error */
/***********************/
/* FUNCTION PROTOTYPES */
/***********************/
plc_defines(); /* defines handles for plc identification */
plc_read(); /* reads info from plc */
plc_err(); /* sets error bits for t/c's & communication */
plc_write(); /* writes info back to plc */
handle_err(); /* error handling routine */
message(); /* message port intercept */
set_com(); /* setup port t1 for communication */
setup_tempscan(); /* sets up the tempscan options */
tempscan_err(); /* check tempscan for errors */
get_temp(); /* get temperature values */
get_val(); /* get temp values a & b */
wait_for_port(); /* wait for input buffer to fill */
flush_port(); /* flush the serial port /t1 */
write_info(); /* writes temp info to data file for off-line access */
close_down(); /* close any open paths and terminate the program */
write_error(); /* write comm error to plc */
/*
* function: main()
*
* main function, this is where it all begins.
*
*/
main(argc,argv)
int argc;
char *argv[];
{
int comflag,i;
struct sgtbuf timebuf;
/* check the command line arguments */
/* argc=number of arguments */
/* argv[] points to the arguments */
if(argc>1)
{
if(!strcmp(argv[1],"exp")) EXP=1;
if(!strcmp(argv[1],"dbg")) DEBUG=1;
if(argc>2)
{
if(!strcmp(argv[2],"exp")) EXP=1;
if(!strcmp(argv[2],"dbg")) DEBUG=1;
}
}
ev_id=_ev_creat(0,1,1,"monitor_ev"); /* create the monitor signal event */
if(ev_id==-1) ev_id=_ev_link("monitor_ev");
CC_INIT(); /* initialize co-processor */
comm_err=0x0000; /* set comm_err to 0 */
intercept(message); /* setup message handler */
if(plc_defines()) comflag=set_com(); /* attempt to setup communications port */
else close_down();
if(!comflag)
{ /* if attempt fails, try 3 more times */
for(i=0;i<3;i++)
{
comflag=set_com();
if(comflag) break;
}
comm_err=comm_err|0x0010; /* if total failure, set comm_err bit */
plc_write(); /* write the failure bits to the plc */
} /* since comflag is not set, we exit */
if(DEBUG)
{
CLR();
MOVE(1,1);
}
while(comflag)
{
getime(&timebuf); /* get the current time */
timebuf.t_second=0x00; /* set the seconds to 0 */
setime(&timebuf); /* reset the current time */
if(get_temp()) /* read all temp values from tempscan */
{ /* successfully read temp values */
if(!plc_read()) comflag=FALSE; /* read all values from plc */
plc_err(); /* check t/c's for errors */
tempscan_err(); /* check tempscan for errors */
if(!plc_write()) comflag=FALSE; /* write all values to plc */
}
else /* timeout error */
{
loop_time[0]=3; /* shorten waiting time */
if(!write_error()) comflag=FALSE; /* write comm error to plc */
}
write_info(); /* write temp data to file */
_ev_set(ev_id,255,0x8000); /* signal monitor process to proceed */
do{
getime(&timebuf); /* get the current time */
}while(timebuf.t_second<loop_time[0]); /* wait for loop time to expire */
_ev_set(ev_id,0,0x8000); /* signal monitor process to wait */
}
close_down(); /* we exit the program entirely on any permanent error involving set-up */
}
/* END OF MAIN FUNCTION */
/*
* function: plc_defines(void)
*
* This function defines the handles that the co-processor will
* use to access information in the PLC.
*/
plc_defines()
{
unsigned int err,iostat; /* error number */
if(DEBUG) printf("In function PLC_DEFINES\n");
err=DTL_INIT(7); /* initialize data table library */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(1,err,0))
return(FALSE);
err=DTL_C_DEFINE(&tc_a_id,"N12:001,112,LONG,MODIFY"); /* define handle tc_a_id */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(2,err,0))
return(FALSE);
err=DTL_C_DEFINE(&tc_b_id,"N13:001,112,LONG,MODIFY"); /* define handle tc_b_id */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(3,err,0))
return(FALSE);
err=DTL_C_DEFINE(&tc_err_id,"N23:001,112,ULONG,MODIFY"); /* define handle tc_err_id */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(4,err,0))
return(FALSE);
err=DTL_C_DEFINE(&tc_setpt_id,"N15:000,8,LONG,MODIFY"); /* define handle tc_setpt_id */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(5,err,0))
return(FALSE);
err=DTL_C_DEFINE(&loop_time_id,"N15:008,2,LONG,MODIFY"); /* define handle loop_time_id */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(6,err,0))
return(FALSE);
err=DTL_C_DEFINE(&comm_err_id,"N15:010,1,ULONG,MODIFY"); /* define handle comm_err_id */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(7,err,0))
return(FALSE);
err=DTL_C_DEFINE(&copro_err_id,"N15:011,2,ULONG,MODIFY"); /* define handle copro_err_id */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(8,err,0))
return(FALSE);
return(TRUE);
}
/* END OF PLC_DEFINES FUNCTION */
/*
* function: plc_read
*
* Reads all information from plc as defined by the plc_defines function.
*
*/
plc_read()
{
unsigned int err,iostat; /* error number */
if(DEBUG) printf("In function PLC_READ\n");
err=DTL_READ_W(tc_setpt_id,tc_setpt,&iostat); /* read t/c range setpoint values from plc */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(11,err,iostat))
return(FALSE);
err=DTL_READ_W(loop_time_id,loop_time,&iostat); /* read loop time value from plc*/
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(12,err,iostat))
return(FALSE);
return(TRUE);
}
/* END OF PLC_READ FUNCTION */
/*
* function: plc_err
*
* checks t/c values against hi/lo range setpoints and sets error bits
* in the tc_err[] array.
*
*/
plc_err()
{
int index; /* loop index */
if(DEBUG) printf("In function PLC_ERR\n");
for(index=0;index<8;index+=2)
tc_setpt[index+1]=tc_setpt[index]; /* copy the setpoint value to the indication value */
loop_time[1]=loop_time[0]; /* copy the loop time setpoint to the loop indication value */
for(index=0;index<108;index++)
{
tc_err[index]=0; /* clear any previously set bits */
if(tcval_a[index]>tc_setpt[0]) tc_err[index]=1;
if(tcval_a[index]<tc_setpt[2]) tc_err[index]=1;
if(tcval_b[index]>tc_setpt[0]) tc_err[index]=tc_err[index]|2;
if(tcval_b[index]<tc_setpt[2]) tc_err[index]=tc_err[index]|2;
}
for(index=108;index<112;index++)
{
tc_err[index]=0; /* clear any previously set bits */
if(tcval_a[index]>tc_setpt[4]) tc_err[index]=1;
if(tcval_a[index]<tc_setpt[6]) tc_err[index]=1;
if(tcval_b[index]>tc_setpt[4]) tc_err[index]=tc_err[index]|2;
if(tcval_b[index]<tc_setpt[6]) tc_err[index]=tc_err[index]|2;
}
}
/* END FUNCTION PLC_ERR */
/*
* function: plc_write()
*
* Write all t/c values & error information to the plc registors
*
*/
plc_write()
{
unsigned int err,iostat; /* error number */
if(DEBUG) printf("In function PLC_WRITE\n");
err=DTL_WRITE_W(tc_err_id,tc_err,&iostat); /* write tc_err array to plc */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(16,err,iostat))
return(FALSE);
err=DTL_WRITE_W(tc_setpt_id,tc_setpt,&iostat); /* write tc_setpt array to plc */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(17,err,iostat))
return(FALSE);
err=DTL_WRITE_W(loop_time_id,loop_time,&iostat); /* write loop_time array to plc */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(18,err,iostat))
return(FALSE);
err=DTL_WRITE_W(tc_a_id,tcval_a,&iostat); /* write tcval_a array to plc */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(14,err,iostat))
return(FALSE);
err=DTL_WRITE_W(tc_b_id,tcval_b,&iostat); /* write tcval_b array to plc */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(15,err,iostat))
return(FALSE);
if(!write_error())
return(FALSE);
return(TRUE);
}
/* END FUNCTION PLC_WRITE */
/*
* function: write_error()
*
* Write error communication errors to plc
*/
write_error()
{
unsigned int err,iostat;
comm_err=comm_err|0x0001; /* set the heart-beat bit */
err=DTL_WRITE_W(comm_err_id,&comm_err,&iostat); /* write comm_err to plc */
if(err!=DTL_SUCCESS) /* check for errors */
if(!handle_err(19,err,iostat))
return(FALSE);
return(TRUE);
}
/* END FUNCTION ERROR_WRITE */
/*
* function: handle_err
*
* Recieves 2 numbers, the function id number, and the plc err number.
* function id refers the function in the program. number is hard-coded.
* plc error number is the actual error id number returned by the function
*
*/
handle_err(id,err,io_err)
int id;
unsigned int err;
unsigned int io_err;
{
unsigned int iostat;
if(DEBUG)
{
printf("In function HANDLE_ERR\n");
printf("Error: ID=%2d %s\n",id,CC_ERROR(err));
}
copro_err[0]=id;
copro_err[1]=err;
iostat_err=io_err;
DTL_WRITE_W(copro_err_id,copro_err,&iostat);
if(id==1) /* data table initialization failed */
{
if(err==17) /* DTL_E_NO_MEM not enough memory */
return(FALSE);
}
if(id>1&id<9) /*
return(FALSE);
if(id>8) /* plc_read & write operations */
{
switch(err)
{
case 19: /* DTL_E_NOINIT define table not initialized */
return(FALSE);
case 20: /* DTL_E_BADID definition id out of range */
return(FALSE);
case 32: /* DTL_E_NODEF no such data item defined */
return(FALSE);
case 41: /* DTL_E_CNVT data conversion error */
return(FALSE);
}
}
return(TRUE);
}
/* END FUNCTION HANDLE_ERR */
/*
* function: message();
*
* Sets background task of handling messages sent to this
* process. in this case, testing for CTRL C & CTRL E
* for program exit.
*/
message(signal)
int signal;
{
switch(signal)
{
case 2: /* ^E */
close_down();
break;
case 3: /* ^C */
close_down();
break;
default:
break;
}
}
/* END FUNCTION MESSAGE */
/*
* function: set_com
*
* opens a stream (path) to serial port /t1
* and sets up the tempscan/1000a
* the port parameters are set in the batch file
* setcom to 9600 baud, 8 data bits, 1 stop bit
* no parity, RTS/CTS handshaking
*/
set_com()
{
int sts,i;
if(DEBUG) printf("In function SET_COM\n");
path=open("/t1",(0x03)); /* open t1 for reading & writing */
if(!path)
{
if(DEBUG) printf("T1 not opened for read/write\n");
return(FALSE);
}
flush_port(); /* flush the serial port /t1 */
setup_tempscan(); /* set the tempscan options */
return(TRUE);
}
/* END FUNCTION SET_COM */
/*
* function: setup_tempscan
*
* sets up all the relevant tempscan options
* prior to use.
*
*/
setup_tempscan()
{
if(EXP)
write(path,"C1-224,1X",10); /* set channels 1-224 to type J (7 cards)*/
else
write(path,"C1-192,1X",10); /* set channels 1-192 to type J (6 cards)*/
write(path,"F0,0X",6); /* set to degrees centigrade */
write(path,"Q6,1,0,0,0X",12); /* set terminator to CR */
}
/* END FUNCTION SETUP_TEMPSCAN */
/*
* function: tempscan_err()
*
* checks for tempscan errors
*
*/
tempscan_err()
{
int i,sts;
char buffer[5];
if(DEBUG) printf("in function TEMPSCAN_ERR\n");
comm_err=comm_err&0xfffb; /* clear the comm error bit */
write(path,"E?X",3); /* check for errors */
_ss_enrts(path); /* assert RTS high*/
sts=wait_for_port(5);
if(sts>0)
{
for(i=0;i<sts;i++)
read(path,&buffer[i],1); /* grab the charactors & put them in the buffer */
_ss_dsrts(path); /* assert RTS low*/
strcpy(temp_err,buffer);
if(DEBUG) printf("Error=%s\n",buffer);
buffer[4]=NULL;
buffer[0]='0';
i=roundoff(buffer); /* convert error buffer into an integer */
}
else
{
_ss_dsrts(path);
if(DEBUG) printf("Timeout\n");
}
if(!i&0xdf)
comm_err=comm_err|0x0004; /* set the comm error bit */
return(TRUE);
}
/* END FUNCTION TEMPSCAN_ERR */
/*
* function: get_temp()
*
* retrieve temperature values from tempscan unit
*
*/
get_temp()
{
int i,j,k;
char buff[10],buff1[10],buff2[10],buff3[10],buffer[40];
if(comm_err&0x0002) /* previous scan had time out error */
{
flush_port(); /* flush the serial port */
setup_tempscan(); /* set up tempscan */
}
j=0;
for(i=1;i<192;i+=4) /* parse thru t/c values in groups of 4 */
{
if(!get_val(i,buffer)) /* grab a string containing 4 values */
return(FALSE); /* timeout error has occured */
for(k=0;k<8;k++) /* break the string into 4 strings */
{
buff[k]=buffer[k];
buff1[k]=buffer[k+10];
buff2[k]=buffer[k+20];
buff3[k]=buffer[k+30];
}
tcval_a[j]=roundoff(buff); /* turn the string into an integer and */
tcval_b[j]=roundoff(buff1); /* place it into the appropriate tc_val */
tcval_a[j+1]=roundoff(buff2);
tcval_b[j+1]=roundoff(buff3);
j+=2;
if(j==76) j=92;
}
if(EXP) /* if the heater expansion option is true */
{
j=76;
for(i=193;i<224;i+=4) /* parse thru t/c values in groups of 4 */
{
get_val(i,buffer); /* grab a string containing 4 values */
for(k=0;k<8;k++) /* break the string into 4 strings */
{
buff[k]=buffer[k];
buff1[k]=buffer[k+10];
buff2[k]=buffer[k+20];
buff3[k]=buffer[k+30];
}
tcval_a[j]=roundoff(buff); /* turn the string into an integer and */
tcval_b[j]=roundoff(buff1);/* place it into the appropriate tc_val */
tcval_a[j+1]=roundoff(buff2);
tcval_b[j+1]=roundoff(buff3);
j+=2;
}
}
return(TRUE);
}
/* END FUNCTION GET_TEMP */
/*
* function: get_val()
*
* actually retrieves requested information
* and returns the temperature value for
* that zone. returns -1 on error
*
*/
get_val(num,buff)
int num;
char *buff;
{
int i,sts;
char request[8];
if(DEBUG) printf("in function GET_VAL\n");
sprintf(request,"R#%d-%dX",num,num+3); /* request will hold the string */
write(path,request,strlen(request)); /* request value */
_ss_enrts(path); /* assert RTS high*/
sts=wait_for_port(38); /* wait for the serial port to fill */
if(sts>0)
{
for(i=0;i<sts;i++)
{
read(path,&buff[i],1); /* grab the waiting charactors */
if(buff[i]<32) buff[i]=' '; /* replace non-printable charactors */
} /* with a space */
}
else
{
if(DEBUG) printf("TIMEOUT\n");
_ss_dsrts(path);
return(FALSE);
}
_ss_dsrts(path); /* assert RTS low*/
return(TRUE);
}
/* END FUNCTION GET_VAL */