Remarks/questions to "mpi_p_g2.c"

We have two programs which are used for testing our fee boards. One is just for general testing like looking on different channels, crosstalk, etc. ("mpi_tes2.c"), while the other one ("mpi_p_g2.c") is for fast testing of many fee boards.

In the end both programs should do the same more or less. The first program has some additional functions for displaying the results (like a scope function e.g.). The second one calculates with the results of the tests some values which give some information about the goodness of the fee card.

In the following I will look into "mpi_p_g2.c" because this is the program which we need to understand as much as possible. Also I will compare this program with the other software "mpi_tes2.c". In the attached listing I've written my comments in bold face.

First of all I have indented the program to get a better overview. You can access the original (unindented) code here, while the indented code (without comments) can be found here. If you want to download everything at once try this.

And now let's start...

#include "C:\LW\INCLUDE\analysis.h"
#include "C:\LW\INCLUDE\formatio.h"
#include "C:\LW\INCLUDE\lwsystem.h"
#include "C:\LW\INCLUDE\userint.h"
#include "C:\LW\INCLUDE\dataacq.h"

/*________________________________________ FEE_P_G1.C  as of 7/24/97
 *                                                          Version 1.0
 *     SCA_Prd4.c provides a user interface to National Instrument's  5/19/94
 *  LabWindows on a IBM-PC clone.  High-level Data Acquisition Library
 *  functions calls are used to control LBL's new IC tester hardware.
 *  Digital control and data acquisition is accomplished through a PC-DIO-96
 *  Digital Board and analog data acquisition is accomplished through a
 *  MIO-16H-25 Analog Board.
 *
 *     This version of the IC Tester software is designed for LBL/BNL to
 *  test production versions of the STAR project's 16-channel SCA chips.
 *  Other variations of this software are designed to test 4-channel preamps,
 *  16-channel preamps, and 16-channel shaper-amp, and combined 16-channel
 *  preamp/shaper-amp chips.
 *
 *     The IC tester for the SCA chips is controlled through digital ports
 *  6..11 on the PC-DIO-96 board.  Ports 6,7,8, and 11 are output only.
 *  Writing to these output ports configures the IC tester for the desired
 *  tests.  Ports 9 and 10, on the PC-DIO-96 board. are used as a bi-
 *  directional data bus.  Digital SCA data are read through digital ports
 *  9 and 10.  Handshaking isDISABLED
 *     Electrical characteristics of the IC under test, are read from input
 *  (ADC) channel 0 of the MIO-16H-25 Analog \Board.  Channel 0 is configured
 *  for differential double ended input, bipolar (-10 to +10 volts), a gain
 *  of 1, and with no external conversion pulses or triggering.
 *
 *  Revision History:
 *  -----------------
 *  1/10/94  Paul Barale    Copied v1 of SCA_Wolf.c and modified for STAR
 *  2/09/94  Paul Barale    Now using FEE_pro1.uir, FEE_PROD.H
 *  2/09/94  Paul Barale    Now using SCA_PROD.DAT as test results file
 *  2/10/94  Paul Barale    Added 'glitch_Num[NUM_CHAN]' to log glitches/chan
 *  2/11/94  Paul Barale    Added 'result' variable
 *  2/14/94  Paul Barale    Added saveTestData() routine to log test results
 *  2/15/94  Paul Barale    Reset data arrays prior to data acquisition
 *  3/03/94  Paul Barale    Modified code to open save file after chip test
 *                          is complete for each chip, log data, then close
 *                          save file
 *  3/11/94  Paul Barale    Pedestal noise failure now go to bin 3, pedestal
 *                          glitch to bin 4, instead of visa-versa
 *  4/19/94  Paul Barale    Copied SCA_PROD.C to SCA_PRD1.C to make executable
 *                          only version
 *  4/21/94  Paul Barale    Copied SCA_PRD1.C to SCA_PRD2.C to clean up and
 *                          shrink program size - removing the following routines
 *                          which are not used: Comp_MemEnable, IncAddrCntr,
 *                          LogSCA, LogSCAo, RunDiagTest, SelectEvenChanels,
 *                          SelectOddChanels, SelSAsig, WriteJigMem, LogTestData,
 *                          and WriteHeader
 *  5/09/94  Paul Barale    Added 4 DC tests to monitor DAC output vs CH0 input -
 *                          check for DAC long term drift - doesn't cause chip rejection
 *  5/11/94  Paul Barale    Added save of cross talk cells / chan and max cross talk
 *                          value / chan
 *  5/12/94  Paul Barale    Found error in firstCell array for cross talk measurement -
 *                          first cell for ch15 pusling was set to same as for ch14.
 *  5/13/94  Paul Barale    Added read of ch0 input voltage to linearity routine, replace
 *                          use of nominal input voltage
 *  5/16/94  Paul Barale    Modified RunDcTest routine to connect mux to ground after
 *                          finished with dc test - had been left to ch 0 input and was
 *                          affecting following measurements.
 *  5/19/94  Paul Barale    Moved calculation transpose and inverted matrices from start
 *                          of program into RunLinearity routine to make use of measured
 *                          ch0 input voltage.
 *  5/23/94 Paul Barale     Installed at BNL as SCA_PROD.C
 *
 *  3/18/96 Chinh Vu     a) change linearity to test # 3
 *                       b) sigma = sigma*(1000/gain) millivolts  (not in ADC counts)
 *                       c) change SCA_LMT.DAT for new limits
 *  3/19/96 Chinh Vu        Add function SCA_DataAcq() before call MeasurePedestal()
 *                          in noise test to get rid of noise step from T.B ~16 (???)
 *  3/20/96 Chinh Vu     a) Add function JumpBit(), SelExtsignal() after             These funtions are never called!
 *                          crosstalk() to check for jumping Bits.
 *                       b) Add function NewRampR() to calculate the new Ramp        This funtion is never called either!
 *                          resistance to have correct Gain .
 *  6/12/96 Chinh Vu     a) Add function SCA_DataAcq() right after Power to Tester is ON
 *                          to get Rid of first Bad Data set this set of data alway higher
 *                          than the second set if power is not OFF (seem working) particular
 *                          on the Pentium .
 *                       b) On Sigma test ,when scan for Bad_Sigma_Cell ,first cell is 10 not 0
 *                       c) Add array ChanMaxjump[NUM_CHAN],ChanNumJump[NUM_CHAN] in Globals.h
 *                          to store maximum jump per chan and Number of Jump per chan .
 *                       d) Change order of SaveTestData to match test panel .
 *  6/21/96  Chinh Vu    a) run JumpBit at 3 voltages 4.75,5.00,5.25 v
 *
 *  9/11/96  Chinh Vu    a) change slope calculation based on current gain  (@90MHz &28.7K)
 *                       b) change Resistor table.
 *                       c) change gain equation for standard R by taking intercept away .
 *                       d) Add chipIDs scan on acse PROD_RUN to skip the RETURN key
 *
 *  2/13/97  Chinh Vu    a) change sca_p_t6.c to Fee_p_t1.c for fee production test
 *                       b) Change function RunDCTest() to accept new kind of test
 *                          in fee Also change Fee_Plim.dat (from 12 to 14 )
 *                       c) Add  NUM_CHAN_B , NUM_SCA to  Fee.H
 *                       d) Modify function MeasurePedestal () to calculate and save ped
 *                          and RMS noise on any number of SCA per FEE bd ( typical 2->4 )
 *                          By repeat the same function NUM_SCA times (new_chan)
 *
 *  2/14/97  Chinh Vu    a) Add RunCal() to calculate Sum of calibration pulse/chan
 *                          and Add MAX_CAL_SUM , MIN_CAL_SUM ,MAX_PUL_SUM ,
 *                          MIN_PUL_SUM to FEE.H
 *
 *  2/21/97  Chinh Vu    a) Add run GlitchBaseLine() to noise test
 *                       b) Add runCrosstalkFee() to pulse every single chan every
 *                          32 TBs and calculate crosstalk on all Un-pulsed channels     TB = TimeBin
 *                          after substract baseline switching of shift register
 *                       c) the runCrossTalkFee() can be modified to calculate the Gain
 *                          linearity (using sum of ~4 TBs of the pulse) by changing
 *                          the DAC1 value for every pulse levels.
 *
 *  7/11/97  Chinh Vu    a) Modified (from FEE_P_T9.C) Function RunCal() to Run ~10 time ,each time
 *                          DAC0 value is change from -5v to -4v for FEE GAIN calculation
 *                          ( DAC0 is connected to SAS_VDC U77-10 )
 *
 *  7/23/97  Chinh Vu    a) Add the calculation of Cal linearity ( from Cal_min to cal_max )   This is commented out at its location in the code!
 *                          on Runcal()
 *
 *  3/18/98  Chinh Vu    a) Add the calculation of percent fail of each test
 *
 *  10/7/98  Chinh Vu    a) this MPI_P_G2.C is from FEE_P_G1.C .
 *
 *  S/W Validation Results:
 *  -----------------------
 *  2/15/94  Paul Barale    Ran program with a variety of known good and bad
 *                          SCA/ADCs - chips measured and data logged ok.
 *  9/11/96  Chinh Vu       Ran program with a variety of known good and bad
 *                          SCA/ADCs - chips measured and data logged ok.
 */

/*+

  _ INCLUDES _______________________________________________________________
 *
 *  Never modify the contents of the "SCA.Prod.h" include file.  It is
 *  generated by the User Interface Editor.
 */
#include "fee.h"       /* Include file for Switched Capacitor Array Chip  */
#include "fee_Pro1.h"  /* Panel parameters from the User Interface Editor */
#include "ni_defs.h"   /* Info specific to National Instrument's boards   */
#include "globals.h"   /* Global parameters                               */

static int start,sca;                 /* to calculate new_chan for data storage */
static int testDataOn;            /* Controls generation of H/W test data */
static int row;                   /* give the box# to store data file */
static int glitch_Num[NUM_CHAN_B];  /* number of glitches in each channel   */
/* static int ChanNumJump[NUM_CHAN_B]; */
/* static int chanCrsTlk[NUM_CHAN_B] ;  */
/* static int chanMaxCtlk[NUM_CHAN_B] ; */

static int Num_tested_bd,State;
static int Num_good ,Percent_good;
static int Num_fail_dc ,Percent_fail_dc;
static int Num_fail_cross ,Percent_fail_cross;
static int Num_fail_lin ,Percent_fail_lin;
static int Num_fail_noise ,Percent_fail_noise;
static int Num_fail_glitch ,Percent_fail_glitch;
static int Num_fail_visual ,Percent_fail_visual;

static double PulseChanSum[NUM_CHAN_B] ;       /* Sum (2TBs) of CrossTalk pulse/chan   */
static double Cal_chan[12][NUM_CHAN_B];            /* Sum (4TBs) of Cal pulse value/chan   */
static double Crosstalk_chan[NUM_CHAN_B][2];   /* maximum crosstalk value & value/chan */
static double CrossTalkTemp[NUM_CELLS][NUM_CHAN];
static double SCA[NUM_CELLS][NUM_CHAN];        /* SCA readout value       */
static double SCAo[NUM_CELLS][NUM_CHAN];       /* Mean SCA Pedestal value */
static double sigmaSCAo[NUM_CELLS][NUM_CHAN];  /* Sigma of Pedestal value */

static double SCAo_chan [NUM_CHAN_B];      /* Mean Pedestal value/channel   */
static double sigmaSCAo_chan[NUM_CHAN_B];  /* Sigma SCA Pedestal value/chan */

static double SCA_chan [NUM_CHAN_B];             /* Mean SCA value/channel  */
static double sigmaSCA_chan[NUM_CHAN];         /* Sigma SCA value/chan    */

static double voltSCA[11];                /* SCA voltage array */

static char result[100];

/* Variables for the overdetermined matrix equation "m = B x c" for a     */
/* least squares estimate of the unknown linearity coefficients c, which  */
/* are the offset and gain for each SCA channel.                          */
static double c[2][NUM_CHAN_B];              /* Unknown least squares const */
static double B[NUM_LIN][2];               /* Least squares input const.  */
static double BT[2][NUM_LIN];              /* Transpose of matrix B       */
static double BTB[2][2];                   /* Matrix product BT x B       */
static double invBTB[2][2];                /* Inverse of matrix BTB       */
static double invBTB_BT[2][NUM_LIN];       /* Inverse of matrix BTB       */
static double m[NUM_LIN][NUM_CHAN_B];        /* Measured linearity values   */
static double fit[10][NUM_CHAN_B];           /* Least squares fit           */
static double fitDiff[NUM_LIN][NUM_CHAN_B];  /* Diff. data - least sq. fit in ADC count  */
static double Percent_fitDiff[NUM_LIN][NUM_CHAN_B];  /* Diff. data - least sq. fit in ADC count  */
static double G[8][4] ;                    /* standard res table */
static double firstCell[NUM_CHAN];              /* First CrossTalk cell   */

/*_ FUNCTION DECLARATIONS ________________________________________________
 */

/*_ SCA FUNCTIONS _______________________________________________________*/
int  ClearCounters();       /* Clear Counters and prepare for new event  */
int  CrossTalkValue();      /* Calculates single cross talk measure      */
int  GlitchValue();         /* Calculates single glitch measure          */
int  HitPanel_PRD( int );   /* Process events for Panel_PRD              */
int  HitPanel_SAW( int );   /* Process events for sawtooth Panel_SAW     */
int  JumpBit();             /* To check the Jumping Bit with Slow Ramp */      This function is never called!
double LinearityValue();    /* Maximum deviation from a linear fit       */
int  MeasurePedestal();     /* Measure mean & sigma of pedestal samples  */
int  Mem_CompEnable();      /* Enable jig memory to computer transfers   */
int  NewRampR();            /* Calculate new R ramp value */                   This function is never called!
int  ReadCrossTalk0();      /* Read baseline data for cross talk calc.   */    This function is never called!
int  ReadCrossTalk();       /* Read cross talk data from test jig's mem. */    This function is never called either!
int  ReadJigMem();          /* Read values from SCA test jig's memory    */
int  ReadSawtooth();        /* Read sawtooth data from test jig's memo   */
int  RunCal();              /* Run Calibration pulse Test on SAS       */
int  RunCrossTalkFee();     /* Run Cross Talk Functional SCA Test        */
int  RunCrossTalk();        /* Run Cross Talk Functional SCA Test        */    This function is never called!
int  RunDcTest( int );      /* Run single DC test on SCA IC Tester       */
int  RunDcTests();          /* Run 16 DC tests on SCA IC Tester          */
int  RunFuncTest( int );    /* Run single Func test on SCA IC Tester     */
int  RunGlitchBaseline();   /* Run Glitch on Baseline test               */
int  RunLinearity();        /* Run Linearity test                        */
int  RunParamTest( int );   /* Run single Param tests on SCA IC Tester   */
int  RunSawTooth();         /* Run Sawtooth Parametric SCA Test          */
int  RunSigmaPedestal();    /* Run Sigma of Pedestal test                */
int  SaveTestData();        /* Writes selected test parameters to file   */
int  SCA_DataAcq();         /* Causes the SCA chip to acquire data       */
int  SCA_MemEnable();       /* Enable SCA to jig memory transfers        */
int  SCA_MemTest();         /* Enable SCA Test Data to jig transfers     */
int  SelDCsig();            /* Select DC signal into SCA chip            */
int  SelDCsigOddEven();     /* Select DC signal into odd/even SCA cells  */    This function is never called!
int  SelectAllChanels();    /* Select all 16 input channels of SCA chip  */
int  SelExtsig();           /* Select External signal into SCA chip      */    This function is never called!
int  SelTriangSig();        /* Select triangular signal into SCA chip    */    This function is never called (but it should -> sawtooth test)!
int  Set_SCA_Volts(double); /* Sets DC level voltage to SCA inputs       */
int  SigmaPedestalValue();  /* Calculates single sigma measure           */
int  StartNewEvent();       /* Set SCA trigger high                      */
int  StrobeData();          /* Store Data in SCA test jig's memory       */
int  TestJigStatus();       /* Read test jig status.  Not 0 ==> ready    */
int  WalkingPulse();        /* Selects non-overlapping SCA input pulses  */    This function is never called!


/*_ COMMON FUNCTIONS ____________________________________________________*/
void Check_Err( int );           /* Display/clear errors WAIT/NO_WAIT    */
int  DIO_Clear();                /* Clear the PC-DIO-96 board's ports    */
int  DIO_Init();                 /* Init PC-DIO-96 lower 6 ports output  */
int  Display_ADC_Port_0();       /* Display status of ADC port 0         */
int  Get_Low_High_Limits( double [][3] );
void ReadParameters( int );      /* Read Parameters from a disk file     */    This function is never called!
void RingBell( int );            /* Ring computer bell "n" times         */
int  Set_PA_Volts( double );     /* Sets the PA power supply voltage     */
double Sigma( double[], double );/* Compute the Standard Deviation       */
void WriteParameters( int );     /* Write Parameters to disk file        */    This function is never called!


void main()
{
    int analogBoardType;    /* 6 for a MIO-16H-25 board            */
    int digitalBoardType;   /* 12 for a PC-DIO-96 board            */
    int itemSelected;       /* ID of control that caused the event */
    int handleHit;          /* For panel or menu bar event         */
    int numSpec;            /* Used for reading/writing param file */
    int fileNum;            /* Extension of the current data output*/
    /* file                                */
    int testVal;            /* counter used for init'ing data arrays*/
    int cal_level;
    double cal_max,cal_min;
    errNum = 0;                   /* Initial value of error #      */
    Fmt( errStr,  "" );           /* Initial value of error string */
    errCount = 0;                 /* Initial value of error count  */
    
    testDataOn = 0;               /* No test data is the default   */
    productionRun = TRUE;         /* Production run is the default   */
    
    /* Open and display user panel */
    errNum = OpenInterfaceManager();
    Check_Err( WAIT );
    
    Panel_PRD = LoadPanel( "FEE_pro1.uir", PRD );
    
    if ( Panel_PRD < 0 ) {
	FmtOut("Unable to load the FEE_pro1.uir resource file.\n");
	return;
    }

    errNum = DisplayPanel( Panel_PRD );
    errNum = SetActivePanel( Panel_PRD );
    Check_Err( WAIT );
    
    Panel_SAW = LoadPanel( "FEE_pro1.uir", SAW );
    
    if ( Panel_SAW < 0 ) {
	FmtOut("Unable to load the FEE_pro1.uir resource file.\n");
	return;
    }

    /*_ INITIALIZATION ____________________________________________________
     */
    
    Fmt( paramFileName, "FEE_FILE.EXT" );
    fileExists = GetFileInfo( paramFileName, &fileSize );
    
    if ( fileExists ) {
	parameterFile = OpenFile( paramFileName, READ_ONLY, NO_TRUNC, ASCII );
	numSpec = ScanFile( parameterFile, "%s>%i", &fileNum );
	errNum = CloseFile( parameterFile );
    }
    
    else {   /* Initialize default parameters */
	fileNum = 0;
    }
    
    Fmt( chipIDs, "");
    Fmt( operatorName, "Fee_revE_JW" );
    Fmt( dataFileName, "PRD_DATA\\MPI_FEE." );
    Fmt( dataFileName, "%s[a]<%d", fileNum );
    fileNum += 1;
    
    if ( fileNum > 999 ) fileNum = 0;

    parameterFile = OpenFile( paramFileName, WRITE_ONLY, TRUNCATE, ASCII );
    numSpec = FmtFile( parameterFile, "%s<%i\n", fileNum ); /* Write file num */
    errNum = CloseFile( parameterFile );
    
    SetCtrlVal( Panel_PRD, PRD_CHIP_ID, chipIDs );
    
    hwDebug = OFF;                   /* ON => leave power to IC tester on.      */
    hwSimulation = OFF;              /* Sim ON required to test S/W without H/W */
    if ( ! hwSimulation ) SetCtrlVal(Panel_PRD, PRD_OPERATOR_NAME, operatorName );

    Fmt( softwareVersion, "v1.0" );  /* Set software version # */
    Fmt( errorFileName  , "SCA_ER00.TXT" );
    Fmt( limitFileName  , "MPI_pLIM.old" );
    errorLogFile = OpenFile( errorFileName, WRITE_ONLY, APPEND, ASCII );
    
    /* voltSCA array contains the DAC voltage settings necessary to a
       achieve the Cal voltage level from cal_min to cal_max  */
    cal_max = -3.900;        /* to have Large Cal pulse */
    cal_min = -4.700;        /* to have Small Cal pulse */
    
    for ( cal_level = 0 ; cal_level < 10 ; cal_level++) {
	/* to set equally space of cal_level voltage */
	voltSCA[cal_level] = ( cal_max - (cal_max - cal_min)*cal_level/9 );
	B[cal_level][1]= voltSCA[cal_level] ;  /* Input voltage for Linearity Test */    Matrix B is filled here!
    }
    
    /*   voltSCA[0] = -4.000;   */       /* to have Large Cal pulse */
    /*   voltSCA[9] = -4.850;   */       /* to have minimum Cal pulse */
    voltSCA[10] = -4.950;         /* to have pedestal reading  */
    
    B[0][0]=1.0;   /* B[0][1]= -4.000;   Input voltage for Linearity Test 0 */
    B[1][0]=1.0;   /* B[1][1]= -4.100;   Input voltage for Linearity Test 1 */
    B[2][0]=1.0;   /* B[2][1]= -4.200;   Input voltage for Linearity Test 2 */
    B[3][0]=1.0;   /* B[3][1]= -4.300;   Input voltage for Linearity Test 3 */
    B[4][0]=1.0;   /* B[4][1]= -4.400;   Input voltage for Linearity Test 4 */
    B[5][0]=1.0;   /* B[5][1]= -4.500;   Input voltage for Linearity Test 5 */
    B[6][0]=1.0;   /* B[6][1]= -4.600;   Input voltage for Linearity Test 6 */
    B[7][0]=1.0;   /* B[7][1]= -4.700;   Input voltage for Linearity Test 7 */
    B[8][0]=1.0;   /* B[8][1]= -4.800;   Input voltage for Linearity Test 8 */
    B[9][0]=1.0;   /* B[9][1]= -4.850;   Input voltage for Linearity Test 9 */
    
    linearityPopup = FALSE;  /* Determines if the linearity chart is displayed  */
    breakOnFail    = FALSE;  /* Permits operator to adjust lower & upper bounds */
    errNum = Init_DA_Brds( AIO_BD, &analogBoardType  ); /* Halts any operations */
    Check_Err( WAIT );
    errNum = Init_DA_Brds( DIO_BD, &digitalBoardType ); /* Halts any operations */
    Check_Err( WAIT );
    
    errNum = Get_Low_High_Limits( boundsDC );
    Check_Err( WAIT );
    
    errNum = DIO_Init();         /* Init digital I/O ports        */
    Check_Err( WAIT );
    
    errNum = DIO_Clear();        /* Clear PC-DIO-96 ports         */
    Check_Err( WAIT );
    
    outp( PORT_7, 0x00 );        /* Turn Tester Power off */                             (=00000000)
    outp( PORT_6, 0x03 );        /* allow counter to output data 9-14-93 */              (=00000011)
    outp(PORT_11, 0x00);         /* Set bit 7 of Port 11 low to reset counter 9-14-93*/  (=00000000)
    /* modified this table for FEE crosstalk pulsing channel in order of */     
    /* chan 0,2,4,6,8,10,12,14,15,13,11,9,7,5,3,1  start chan 0 @ TB 29  */
    /* and every 32 TB for subsequence channels     2/19/97              */
    firstCell[0]=29;    firstCell[1]=509;    firstCell[2]=61;    firstCell[3]=477;   Where do these numbers come from?
    firstCell[4]=93;    firstCell[5]=445;    firstCell[6]=125;   firstCell[7]=413;
    firstCell[8]=157;   firstCell[9]=381;    firstCell[10]=189;  firstCell[11]=349;
    firstCell[12]=221;  firstCell[13]=317;   firstCell[14]=253;  firstCell[15]=285;
    
    Num_tested_bd   =0;
    Num_good        =0;
    Num_fail_dc     =0;
    Num_fail_cross  =0;
    Num_fail_lin    =0;
    Num_fail_noise  =0;
    Num_fail_glitch =0;
    Num_fail_visual =0;
    
    
    quitTest = FALSE;            /* TRUE when quit key is pressed */
    
    /*_ Main Event Loop ______________________________________________________
     */
    
    while ( !quitTest ) {
	errNum = SetActiveCtrl( PRD_CHIP_ID );
	
	errNum = GetUserEvent( WAIT, &handleHit, &itemSelected );
	
	Check_Err( WAIT );
	
	/* Clear all the data arrays each time through to avoid recording
	   spurrious data                                                    */
	
	for( testVal=0; testVal<NUM_TESTS_DC; testVal++ ) {
	    boundsDC[testVal][1] = 0;
	}

	for( testVal=0; testVal<NUM_CHAN; testVal++ ) {
	    chanCrsTlk[testVal] = 0;
	    chanMaxCtlk[testVal] = 0;
	    ChanNumJump[testVal] = 0;
	    ChanMaxJump[testVal] = 0;
	    sigmaSCAo_chan[testVal] = 0;
	    glitch_Num[testVal] = 0;
	    c[1][testVal] = 1;
	    maxNonLin[testVal] = 0;
	}
	
	/* Select function to process the "itemSelected" for the "hit" panel */
	
	if ( handleHit == Panel_SAW ) errNum = HitPanel_SAW( itemSelected );
	
	else {
	    
	    if ( handleHit == Panel_PRD ) errNum = HitPanel_PRD( itemSelected );
	    else RingBell( 1 );
	}
    }
    
    /* Program ended.  Shut down the hardware and software. */
    
    errNum = DIO_Clear();                               /* Clear PC-DIO-96 ports     */
    errNum = Set_PA_Volts( 0.0 );                       /* Remove power to SCA chip  */
    errNum = Init_DA_Brds( AIO_BD, &analogBoardType  ); /* Halts analog operations   */
    errNum = Init_DA_Brds( DIO_BD, &digitalBoardType ); /* Halts digital operations  */
    errNum = CloseInterfaceManager();                   /* Close user panel          */
    
    /*   parameterFile = OpenFile( paramFileName, WRITE_ONLY, TRUNCATE, ASCII ); */
    /*   WriteParameters( parameterFile );  */                 /* Write updated parameters  */
    /*   errNum = CloseFile(parameterFile); */                 /* Close parameter text file */
    
    errNum = CloseFile(errorLogFile);               /* Close error log text file     */
    
}      /* ______ END of MAIN LOOP _________ */


/*_ Clear Counters __________________________________________________
 *
 *  Function ClearCounters sets the SCA trigger low.  This clears all
 *  counters on the test jig and prepares it for the next event.
 */

int ClearCounters()
{
    outp(PORT_11, 0x00);  /* Set bit 7 of Port 11 low */     (=00000000)
    return(0);
}


/*_ Cross Talk Value ____________________________________________
 *
 *  Function CrossTalkValue calculates the cross talk as the
 *  number of time buckets where the cross talk exceeds a maximum
 *  (max_Ctlk_Counts).
 */

int CrossTalkValue()
{
    int cell, cell1, chan, pulseChan;   /* Loop indices */
    int value,new_chan;
    
    errNum = 0;                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );            /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    value = 0;
    
    for (  chan=0; chan<NUM_CHAN; chan++ ) {
	start = 16*sca ;
	new_chan = chan + start;
	chanMaxCtlk[new_chan] = 0;   /* clear max crosstalk per chan */
	chanCrsTlk[new_chan] = 0;    /* clear num of max crosstalk per chan */
	PulseChanSum[new_chan] = 0;
    }
    
    for ( pulseChan=0; pulseChan<NUM_CHAN; pulseChan++ ) {
	
	for ( chan=0; chan<NUM_CHAN; chan++ ) {
	    /*   if ( chan != pulseChan )  */  /* Not a pulsed channel */
	    
	    if ( chan == pulseChan ) {                                      Look in the same channel...
		start = 16*sca ;
		new_chan = chan + start;
		
		for ( cell=firstCell[pulseChan]; cell<( firstCell[pulseChan]+2); cell++ ) {
		    PulseChanSum[new_chan] += SCA[cell][chan]; /* sum 2TBs of the pulse */
		}
		
		if (( 100 > PulseChanSum[new_chan] )||( PulseChanSum[new_chan] >1800 )) {
		    /*     Breakpoint ();  */
		    passedAllTests = FALSE;   /* pulse size too small OR too big */
		    SetCtrlVal( Panel_PRD, PRD_CTLK_FAIL, ON );
		    SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 2CSIZE" );  CSIZE is not predefinied. So this seems to be the name of a box "2CSIZE".
		    Fmt( result, "%s<%s", "2CSIZE" );                                              Same here...(other versions following (2CROS, 2CAL)
		    SetCtrlVal( Panel_PRD, PRD_CTLK_RUN,  OFF );
		    
		    return(0);    
		}
	    }
	    
	    else {                                                                   Look in the other channels...
		cell1 = firstCell[pulseChan]; /* First cell where glitch expected */
		
		/*    for ( cell=cell1; cell<(cell1+NUM_CTLK_CELLS); cell++ )  */
		for ( cell=cell1; cell<(cell1+2); cell++ )                           I think this is a typo. Here has to be a brace {. 
                                                                                        Otherwise the loop makes no sense at all. 
		    start = 16*sca ;

		new_chan = chan + start; {                                           This brace has to move three lines up!!! 
		    if ( fabs( SCA[cell][chan]) > max_Ctlk_Counts ) {
			value += 1;     /* Count occurences of excessive cross talk */
			chanCrsTlk[new_chan] += 1;
		    }
		    
		    if ( fabs( SCA[cell][chan]) > chanMaxCtlk[new_chan] ) {
			chanMaxCtlk[new_chan] = fabs( SCA[cell][chan]);
		    }
		    
		    if ( chanCrsTlk[new_chan]  > max_Bad_Ctlk_Cells ) {
			passedAllTests = FALSE;
			SetCtrlVal( Panel_PRD, PRD_CTLK_FAIL, ON );
			SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 2CROS" );
			Fmt( result, "%s<%s", "2CROS" );
			SetCtrlVal( Panel_PRD, PRD_CTLK_RUN,  OFF );
			/*    Breakpoint ();   */
			return(0);       /* too many big crosstalk per chan */
		    }
		}
	    }
	}
    }
    
    return( value );
}


/*_ Glitch Value ____________________________________________
 *
 *  Function GlitchValue counts excessive glitches.
 */

int GlitchValue()
{
    int cell, chan;   /* Loop indices */
    int value,new_chan;
    
    errNum = 0;                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );            /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    value = 0;
    
    for ( chan=0; chan<NUM_CHAN; chan++ ) {
	start = sca*16;
	new_chan = chan + start;
	glitch_Num[new_chan] = 0;   /* clear the current Glitch_num[] array */
    }
    
    for ( chan=0; chan<NUM_CHAN; chan++ ) {
	start = sca*16;
	new_chan = chan + start;
	/*    Breakpoint ();  */
	
	for ( cell=FIRST_GOOD_CELL; cell<NUM_CELLS; cell++ ) {
	    
	    if ( fabs(SCAo[cell][chan]-SCAo_chan[new_chan]) > max_Glitch_Counts ) {
		value += 1;     /* Count total occurences of excessive glitchs */
		glitch_Num[new_chan] += 1;  /* keep track of glitches per chan */
	    }
	}
	
	/*     Breakpoint ();    */
    }
    
    return( value );
}


/*_ Linearity Value ________________________________________
 *
 *  Function LinearityValue returns maximum deviation from a
 *  linear least squares fit.
 */

double LinearityValue( int chan )
{
    int    i;                     /* Loop index */
    double value;
    
    errNum = 0;                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );            /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    value = 0;
    
    for ( i=0; i<NUM_LIN; i++ ) {               NUM_LIN = 10
	
	if ( fabs( fitDiff[i][chan] ) > value ) value = fabs( fitDiff[i][chan] );
    
    }
    
    return( value );
}


/*_ Process "itemSelected" on Panel_PRD ______________________
 *
 *  Function HitPanel_PRD responds to the "itemSelected" on Panel_PRD.
 */

int HitPanel_PRD( itemSelected )
     int itemSelected;
{
    int numBytes;     /* Number of bytes written */
    int arrayIndex;
    switch ( itemSelected )
	{
	    
	    /*  case PRD_RUN_TEST:   */                /* user pressed the RUN button */
	case PRD_CHIP_ID:   /* to RUN right after user scanned the chip ID */
	    
	    errNum = GetCtrlVal( Panel_PRD, PRD_CHIP_ID, chipIDs );
	    
	    /* make sure chip ID scanned or entered before doing anything! */
	    if( CompareStrings( chipIDs, 0, "", 0, 0 ) == 0 ) {
		SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "Please scan or type chip ID and RETURN" );
		RingBell( 3 );
	    }
	    
	    /*initialize arrays used to record archived data*/
	    else {
		
		for( arrayIndex=0; arrayIndex<NUM_TESTS_DC; arrayIndex++) {
		    boundsDC[arrayIndex][1] = 0;
		}
		
		for( arrayIndex=0; arrayIndex<NUM_CHAN; arrayIndex++) {
		    sigmaSCAo_chan[arrayIndex] = 0;
		    glitch_Num[arrayIndex] = 0;
		    c[1][arrayIndex] = 0;
		}
		
		for( arrayIndex=0; arrayIndex<NUM_CHAN_B; arrayIndex++) /* for fee BD */ {
		    PulseChanSum[arrayIndex] = 0;
		    chanCrsTlk[arrayIndex] = 0;
		    chanMaxCtlk[arrayIndex] = 0;
		    Cal_chan[0][arrayIndex] = 0;
		    sigmaSCAo_chan[arrayIndex] = 0;
		    glitch_Num[arrayIndex] = 0;
		}
		
		Fmt( result, "%s<%s", " " );
		
		outp( PORT_7, 0xA0 );            /* Turn Tester power on + clear input Shift Register  */ (=10100000)
		errNum = Set_PA_Volts( Vp_nom ); /* Apply nominal power to SCA  */    Vp_nom = 5 V
		SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "  " );
		Check_Err( WAIT );
		
		
		passedAllTests = TRUE;
		
		
		SetCtrlVal( Panel_PRD, PRD_RUN_LED , ON  );
		SetCtrlVal( Panel_PRD, PRD_LED_PASS, OFF );
		SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "Running Production FEE bd Tests" );
		SetCtrlVal( Panel_PRD, PRD_DC_RUN, OFF );
		SetCtrlVal( Panel_PRD, PRD_DC_FAIL, OFF );
		
		SetCtrlVal( Panel_PRD, PRD_CTLK_RUN, OFF );
		SetCtrlVal( Panel_PRD, PRD_CTLK_FAIL, OFF );
		
		SetCtrlVal( Panel_PRD, PRD_SIGMA_RUN, OFF );
		SetCtrlVal( Panel_PRD, PRD_SIGMA_FAIL, OFF );
		
		SetCtrlVal( Panel_PRD, PRD_GLITCH_RUN, OFF );
		SetCtrlVal( Panel_PRD, PRD_GLITCH_FAIL, OFF );
		
		SetCtrlVal( Panel_PRD, PRD_LIN_RUN, OFF );
		SetCtrlVal( Panel_PRD, PRD_LIN_FAIL, OFF );
		
		SetCtrlVal( Panel_PRD, PRD_SAW_RUN, OFF );
		SetCtrlVal( Panel_PRD, PRD_SAW_FAIL, OFF );
		
		errNum = StartNewEvent();   /* to reset the SCA shift register    */    PORT_11 = 10000000
		errNum = ClearCounters();   /* after the power applied to the SCA */    PORT_11 = 00000000
		/* add on 6/12/96 to get rid of first bad data  */
		errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
		delay( 5.0 );                /* Delay 5.0 second after power on */
		
		Num_tested_bd   = Num_tested_bd +1;
		SetCtrlVal( Panel_PRD, PRD_TEST_NUM, 1 );
		State = 1;
		errNum = RunDcTests();           /* Run DC tests                */

		if ( passedAllTests ) {
		    SetCtrlVal( Panel_PRD, PRD_TEST_NUM, 2 );
		    State = 2;
		    errNum = RunCrossTalkFee();     /* Run Cross Talk test         */
		}
		
		if ( passedAllTests ) {
		    SetCtrlVal( Panel_PRD, PRD_TEST_NUM, 3 );
		    State = 3;
		    errNum = RunCal();   /* Run Calibration Linearity test   */
		}
		
		if ( passedAllTests ) {
		    /*        SetCtrlVal( Panel_PRD, PRD_TEST_NUM, 3 );  */
		    /*        errNum = RunLinearity();  */ /* NO NEED to Run Linearity test  */    Why?
		}
		
		if ( passedAllTests ) {
		    SetCtrlVal( Panel_PRD, PRD_TEST_NUM, 4 );
		    State = 4;
		    errNum = RunSigmaPedestal();     /* Run Sigma of Pedestal+ Glitch test  */
		}
		
		if ( passedAllTests ) {
		    /*       SetCtrlVal( Panel_PRD, PRD_TEST_NUM, 5 );  */
		    /*       errNum = RunGlitchBaseline();  */ /* NO NEED TO Run Glitch on Baseline test */  Why?
		}
		
		if ( passedAllTests ) {
		    SetCtrlVal( Panel_PRD, PRD_TEST_NUM, 6 );
		    State = 6;
		    RingBell(2);
		    errNum = RunSawTooth();       /* Run Sawtooth test           */
		}
		
		if ( passedAllTests ) {
		    SetCtrlVal(Panel_PRD, PRD_LED_PASS, ON );
		    State = 7;
		}
		
		else {
		}
		
		SetCtrlVal(Panel_PRD, PRD_RUN_LED, OFF );
		
		
		SaveTestData();
		
		RingBell( 1 );
		/* increase the % of board fail in each box  3/17/98 */
		if ( State == 1) {
		    Num_fail_dc =  Num_fail_dc + 1;
		}
		
		if ( State == 2) {
		    Num_fail_cross =  Num_fail_cross + 1;
		}

		if ( State == 3) {
		    Num_fail_lin =  Num_fail_lin + 1;
		}

		if ( State == 4) {
		    Num_fail_noise =  Num_fail_noise + 1;
		}

		if ( State == 5) {
		    Num_fail_glitch =  Num_fail_glitch + 1;
		}

		if ( State == 6) Num_fail_visual =  Num_fail_visual + 1;

		Percent_fail_dc     = (Num_fail_dc*100)/Num_tested_bd;
		Percent_fail_cross  = (Num_fail_cross*100)/Num_tested_bd;
		Percent_fail_lin    = (Num_fail_lin*100)/Num_tested_bd;
		Percent_fail_noise  = (Num_fail_noise*100)/Num_tested_bd;
		Percent_fail_glitch = (Num_fail_glitch*100)/Num_tested_bd;
		Percent_fail_visual = (Num_fail_visual*100)/Num_tested_bd;
		
		Percent_good = 100-(Percent_fail_dc+Percent_fail_cross + Percent_fail_lin +
				    Percent_fail_noise + Percent_fail_glitch + Percent_fail_visual);
		
		SetCtrlVal(Panel_PRD, PRD_Num_tested_bd,Num_tested_bd );
		SetCtrlVal(Panel_PRD, PRD_Num_fail_dc,Percent_fail_dc );
		SetCtrlVal(Panel_PRD, PRD_Num_fail_cross,Percent_fail_cross );
		SetCtrlVal(Panel_PRD, PRD_Num_fail_lin,Percent_fail_lin );
		SetCtrlVal(Panel_PRD, PRD_Num_fail_noise,Percent_fail_noise );
		SetCtrlVal(Panel_PRD, PRD_Num_fail_glitch,Percent_fail_glitch );
		SetCtrlVal(Panel_PRD, PRD_Num_fail_visual,Percent_fail_visual );
		SetCtrlVal(Panel_PRD, PRD_Num_good,Percent_good ) ;
		
		if ( hwDebug == OFF ) {
		    outp( PORT_7, 0x00 );        /* Turn Tester Power off */                            (=00000000)
		    outp( PORT_6, 0x03 );        /* allow counter to output data 9-14-93 */             (=00000011)
		    outp(PORT_11, 0x00);         /* Set bit 7 of Port 11 low to reset counter 9-14-93*/ (=00000000)
		    errNum = Set_PA_Volts( 0.0 );/* Remove power to SCA   */
		    Set_SCA_Volts( 0 );   /*777*/     /* Sets SAS_VDC to 0v  */
		    Check_Err( WAIT );
		    /*     Fmt( chipIDs, "" );    */
		    SetCtrlVal( Panel_PRD, PRD_CHIP_ID, "" ); /* clear Just tested ID */
		}

		SetCtrlVal( Panel_PRD, PRD_FEE_ID, chipIDs );
	    }
	    
	    break;
	    
	case PRD_OPERATOR_NAME:
	    errNum = GetCtrlVal(Panel_PRD, PRD_OPERATOR_NAME, operatorName);
	    Check_Err( WAIT );
	    break;
	    /*
	      case PRD_WAFER_ID:
	      errNum = GetCtrlVal(Panel_PRD, PRD_WAFER_ID, waferID);
	      Check_Err( WAIT );
	      break;
	    */

	    /*
	      case PRD_CHIP_ID:
	      errNum = GetCtrlVal( Panel_PRD, PRD_CHIP_ID, chipIDs );
	      Check_Err( WAIT );
	      break;
	    */

	    /*   case PRD_INC_CHIP_ID:
		 chipID++;
		 SetCtrlVal( Panel_PRD, PRD_CHIP_ID, chipID );
		 break;
	    */

	case PRD_SAW_PLOT:               /* user pressed the SAW button or F4   */
	    errNum = HidePanel( Panel_PRD );
	    errNum = ClearGraphicsScreen( LT_GRAY );
	    errNum = DisplayPanel( Panel_SAW );
	    errNum = SetActivePanel( Panel_SAW );   /* Activate Panel_SAW        */
	    Check_Err( WAIT );
	    break;
	    
	case PRD_PRINTIT:               /* user pressed the PRINT button */
	    errNum = OutputScreen( -1, null );
	    break;
	    
	case PRD_QUIT:                    /* user pressed the QUIT button       */
	    quitTest = TRUE;
	    errNum = SavePanelState( Panel_PRD, "PanlPRD.DAT" );
	    Check_Err( WAIT );
	    break;
	    
	default: break;
	}
    
    return(0);
}


/*_ Process "itemSelected" on Data Panel "SAW" ________________________
 *
 *  Function HitPanel_SAW responds to the "itemSelected" on Panel "SAW".
 */

int HitPanel_SAW( itemSelected )
     int itemSelected;
     
{
    /*   errNum = OutputScreen( -1, null );  */
    
    switch ( itemSelected )  {
	
    case SAW_HOME:                /* user pressed the HOME button */
	errNum = HidePanel( Panel_SAW );
	errNum = ClearGraphicsScreen( LT_GRAY );
	errNum = DisplayPanel( Panel_PRD );
	errNum = SetActivePanel( Panel_PRD );  /* Activate Panel_PRD       */
	Check_Err( WAIT );
	break;
	
    case SAW_PRINTIT:               /* user pressed the PRINT button */
	errNum = OutputScreen( -1, null );
	break;
	
    case SAW_BAD_IC:                /* user pressed the BAD IC button */
	errNum = HidePanel( Panel_SAW );
	errNum = ClearGraphicsScreen( LT_GRAY );
	errNum = DisplayPanel( Panel_PRD );
	errNum = SetActivePanel( Panel_PRD );  /* Activate Panel_PRD       */
	Check_Err( WAIT );
	passedSawToothTest = FALSE;
	passedAllTests = FALSE;
	SetCtrlVal( Panel_PRD, PRD_SAW_RUN, OFF );
	SetCtrlVal( Panel_PRD, PRD_SAW_FAIL, ON );
	SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 6" );
	
	Fmt( result, "%s<%s", "6" );
	break;
	
   case SAW_GOOD_IC:              /* user pressed the GOOD IC button */
       errNum = HidePanel( Panel_SAW );
       errNum = ClearGraphicsScreen( LT_GRAY );
       errNum = DisplayPanel( Panel_PRD );
       errNum = SetActivePanel( Panel_PRD );  /* Activate Panel_PRD       */
       Check_Err( WAIT );
       passedSawToothTest = TRUE;
       SetCtrlVal( Panel_PRD, PRD_SAW_RUN, OFF );
       SetCtrlVal( Panel_PRD, PRD_LED_PASS, ON );
  /*     errNum = NewRampR() ;      */
       
       SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "GOOD: Put FEE into Box 7" );
       /*    Fmt( result, "%s[a]<%f[p0]", G[row][3] );  */
       Fmt( result, "%s<%s", "7" );
       /*   Fmt( result, "%s<%s", " G[row][3]" );   */
       break;
       
    default: break;
    }
    
    return(0);
}


/* RUN JUMP BIT TEST */

int  JumpBit()                                                    This function is never called!
{
    int turn;
    double V_sca;
    int  chan,cell,cell1,  NumJumpCell;
    NumJumpCell = 0;
    
    V_sca = 4.70 ;  /* set the SCA/ADC P.S voltage at 4.70v */
    
    for ( turn = 0; turn < 3; turn++ ) {
        V_sca = V_sca + 0.15 ;   /* increment the SCA/ADC P.S 150mv */
        errNum = Set_PA_Volts( V_sca );
	delay (1.0);  /* allowed power to settle before the next test */
	errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	errNum = SelExtsig();         /* Select External signal into SCA    */
	Set_SCA_Volts( voltSCA[0] ); /* Sets DC level voltage to SCA inputs */
	delay (1);
	
	errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	errNum = ReadJigMem();
	/*  3/16/96 */
	errNum = 0;
	/* test jump bit only from cell #10 to cell #501  3/11/96 */
        
	for ( cell=10; cell<NUM_CELLS-10; cell++ ) {

	    for ( chan=0; chan<NUM_CHAN; chan++ ) {
		cell1=0;
		cell1=cell+1;
		SCA[cell][chan] -= SCA[cell1][chan];   /* Subtract the data with SCA removed */
		
		if ((SCA[cell][chan] < -5)||(SCA[cell][chan] > 8)) /* 10/13/95 */ {
		    errNum = errNum + 1;
		    ChanNumJump[chan] = ChanNumJump[chan] + 1;
		    
		    if  ( fabs(SCA[cell][chan]) > ChanMaxJump[chan] ) ChanMaxJump[chan] = SCA[cell][chan];
		}
		
		else {
		    SCA[cell][chan] = 0;		
		}
	    }
	}
      
	NumJumpCell = errNum ;
    }
    
    errNum = Set_PA_Volts( 5.00 );  /* reset power supply to 5.00v */
    delay (1.0);  /* allowed power to settle before the next test */
    /*   Breakpoint ();    */
    
    if (NumJumpCell > 4)  /* stop at breakpoint if more than 10 cells had problem */ {
	passedCrossTalk = FALSE;
	passedAllTests = FALSE;
	SetCtrlVal(Panel_PRD, PRD_CTLK_FAIL, ON );
	SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 2" );
	
	/*  if ( V_sca == 4.85 )
	    {
	    Fmt( result, "%s<%s", "2J1" );
	    }
	    if ( V_sca == 5.00 )
	    {
	    Fmt( result, "%s<%s", "2J2" );
	    }
	    if ( V_sca == 5.15 )   */
	
	Fmt( result, "%s<%s", "2J3" );
    }
    
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 100 );
    SetCtrlVal( Panel_PRD, PRD_CTLK_RUN,  OFF );
    
    errNum = SelDCsig();
    return(0);
}


/* 10/18/95  */

/*_ Measure Pedestal __________________________________________________
 *
 *  Function MeasurePedestal applies a zero input signal to an SCA chip
 *  and measures the mean and sigma of the pedestal of each cell.
 */

int MeasurePedestal()
{
    double diff;
    double f;
    double v2;
    int high;
    int cell, chan, samp;  /* Loop indices */
    int v;
    int complete,new_chan,data;
    
    errNum = 0;         /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );  /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 0 );
    
    /*   for ( sca = 0; sca< NUM_SCA ;sca++)
         {                           */
    
    for ( chan=0; chan<NUM_CHAN; chan++ ) {        NUM_CHAN = 16
	
	for ( cell=0; cell<NUM_CELLS; cell++ ) {   NUM_CELLS =512
	    SCAo[cell][chan] = 0.0;      /* Clear Pedestal mean matrix   */
	    sigmaSCAo[cell][chan] = 0.0; /* Clear Pedestal sigma matrix  */
	}
    }

    /*---------------------------------------
     *  Read SCA output from the jig's memory
     */
    for ( samp=0; samp<NUM_SAMPLES; samp++ ) {      The following two lines are not present in "mpi_tes2.c".
	outp(PORT_7, 0x80);          /* set to allow A13,A14 switch by the XILINX */     (=10000000)
	errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory      */
	
	data = 0x80 | sca ;     /* set to read correspont SCA */
	outp(PORT_7, data);
	
	outp(PORT_8, 0x01);          /* Allow counter to be advanced by comp. */         (=00000001)
	Mem_CompEnable();            /* Enable Jig to Computer data transfers */
	ClearCounters();             /* Set Port 11 bit 7 low                 */
	StartNewEvent();             /* Set Port 11 bit 7 high                */
	outp(PORT_8, 0x00);          /* Allow counter to be advanced by comp. */         (=00000000)
	
	for ( cell=0; cell<NUM_CELLS; cell++ ) {
	    
	    for ( chan=0; chan<NUM_CHAN; chan++ ) {
		high = inp( PORT_10 ) & 0xF; /* Read 4 high-order data bits     */   (=xxxx0000)
		v  = inp( PORT_9 );          /* Read SCA jig's 8 low-order bits */       (=yyyyyyyy)
		v |= high << 8;              /* Combine high and low-order bits */ (=xxxxyyyyyyyy)
		f = (double)v;               /* Convert integer to double       */
		SCAo[cell][chan] += f;       /* Sum                             */
		outp(PORT_8, 0x01);          /* Inc Addr Cntr(Port 8 bit 0 high)*/
		outp(PORT_8, 0x00);          /* Strobe Data (Port 8 bit 8 low)  */
		v2 = f*f;                    /* Square                          */
		sigmaSCAo[cell][chan] += v2; /* Sum of value^2 matrix           */
	    }
	}
	
	complete = (50*sca)+50 - ( ( NUM_SAMPLES - ( samp ) ) * 10/NUM_SCA);
	SetCtrlVal( Panel_PRD, PRD_PERCENT, complete );
    }
    
    Check_Err( WAIT );
    /*     Calculate accumulate data after each read    */
    
    for ( chan=0; chan<NUM_CHAN; chan++ ) {
	
	for ( cell=0; cell<NUM_CELLS; cell++ ) {
	    SCAo[cell][chan]  /= NUM_SAMPLES;     /* Calculate mean matrix  */
	    sigmaSCAo[cell][chan] /= NUM_SAMPLES; /* Calculate sigma matrix */
	    v2 = SCAo[cell][chan]*SCAo[cell][chan];
	    diff = sigmaSCAo[cell][chan] - v2;
	    
	    if ( diff <= 0.0 ) sigmaSCAo[cell][chan] = 0.0;
	    
	    else sigmaSCAo[cell][chan] = sqrt( diff );
         
	    if (cell >= FIRST_GOOD_CELL) {    /* Skip spikes in first cells    */
		                              /* Sum of value/channel matrix     */
		start = 16*sca ;              /* change storage chan to new chan */
		new_chan = chan + start;
		
		SCAo_chan[new_chan] += SCAo[cell][chan];
		/* Sum of value^2/channel matrix   */
		sigmaSCAo_chan[new_chan] += sigmaSCAo[cell][chan];
	    }
	}

	SCAo_chan[new_chan] /= (NUM_CELLS-FIRST_GOOD_CELL);      /* Calc mean/chan  */
	sigmaSCAo_chan[new_chan] /= (NUM_CELLS-FIRST_GOOD_CELL); /* Calc sigma/chan */
	/*   sigmaSCAo_chan[chan] =  sigmaSCAo_chan[chan]*1000/c[1][chan] ; */ /* sigma/chan in milivolt */
	sigmaSCAo_chan[new_chan] =  sigmaSCAo_chan[new_chan]*1000/1000 ;  /* sigma/chan in milivolt with gain = 425 count/v */           
    }
    
    /*    Breakpoint ();  */   /* to see storage data of each SCA  */
    errNum = RunGlitchBaseline();      /* fee add this test in RMS */
    /*      }        */

    return(0);
}


/*_ Memory to Computer Enable ______________________________________
 *
 *  Function Mem_CompEnable enables jig memory to computer transfers.
 */

int Mem_CompEnable()
{
    int new, old;
    
    old = inp( PORT_6 );       /* Read port's old value                    */
    new = (old & 0xFC) | 0x1;  /* Set bits 1..0 to 0,1                     */
    outp(PORT_6, new);         /* Enables jig memory to computer transfers */   (=xxxxxx01)
    return(0);
    
}


/* Calculate new R ramp value _______________________________________*/    This function is never called!
int NewRampR()   
     
{
    char   temp[40];
    double gain,resistance;
    double slope,min,d_gain,intercept;
    int    chan, i,R;           /* Loop indices            */
    gain = 0;
    resistance = 0 ;
    intercept = 0;
    slope = 0;
    d_gain = 425;
    
    for ( chan=0; chan<NUM_CHAN; chan++ ) {
	gain = gain + c[1][chan];
    }

    gain = gain / NUM_CHAN;
    Fmt( temp, "%s<%s", "Ave Gain = " );
    Fmt( temp, "%s[a]<%f[p0]", gain );
    /*  add this adjusted GAIN calculation on 2/2/96 C.Vu */
    SetCtrlVal( Panel_PRD, PRD_TEST_RESULT, temp );
    delay (3);
    /* calculate slope (delta G/delta R) based on  gain  */
    /* measured at 51.1 K & 80 MHz PECL shifted ADC_clk )  */
    /*  slope =4.737+(gain-432)*0.012428 ; comment on 6/13/96 */
    /*  intercept = (gain-426)*0.172088 + 83.63 ;  */
    slope = (gain-428)*0.021435 + 8.97697849 ;   /* new slope @ 90 MHz + R_ramp termination */
    /* calculate new GAINs values based on available standard Rs */
    G[0][0]=32.4;G[0][3]=7;     /* standard R and correspond Box */
    G[1][0]=30.9;G[1][3]=8;     /* standard R and correspond Box */
    G[2][0]=28.7;G[2][3]=9;     /* R used on tester and correspond Box */
    G[3][0]=26.7;G[3][3]=10;    /* standard R and correspond Box */
    G[4][0]=24.9;G[4][3]=11;    /* standard R and correspond Box */
    G[5][0]=22.6;G[5][3]=12;    /* standard R and correspond Box */
    G[6][0]=20.5;G[6][3]=13;    /* standard R and correspond Box */
    G[7][0]=18.7;G[7][3]=14;    /* standard R and correspond Box */
    
    for ( R=0; R<8; R++ ) {
	G[R][1] = gain - (G[2][0]-G[R][0])*slope; /*  9/12/96 */
	/*   G[R][1] = slope*G[R][0] + intercept;  */ /* comment 9/12/96 */
    }

    /* calculate the percent difference between the new GAINs and the desired GAIN */
    for ( R=0; R<8; R++ ) {
	G[R][2] = (d_gain - G[R][1])*100/d_gain;
    }
    
    min = fabs(G[0][2]);
    row = 0 ;
   
    for ( R=0; R<8; R++ ) {
	
	if ( G[R][2]<min ) {
	    min = fabs(G[R][2]) ;
	    row = R;
	}
	
	Fmt( temp, "%s<%s", "to have Gain ~ 425 ,put IC in Box = " );
	Fmt( temp, "%s[a]<%f[p0]", G[row][3] );
	SetCtrlVal( Panel_PRD, PRD_TEST_RESULT, temp );
    }
}


/*_ Read Cross Talk Baseline Data _____________________________________         This function is never called!
 *
 *  Function ReadCrossTalk0 reads the baseline cross talk data from the
 *  Test Jig's memory, without pulsing.
 */

int ReadCrossTalk0()
{
    double diff;
    double f;
    int cell, chan;   /* Loop indices */
    int v;
    int high;
    int temp;
    
    errNum = 0;                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );            /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    /*--------------------------------------------
     *  Read values from the SCA Test Jig's memory
     */
    
    outp(PORT_8, 0x01);           /* Allow counter to be advanced by comp. */       (=00000001)
    Mem_CompEnable();             /* Enable Jig to Computer data transfers */
    
    ClearCounters();              /* Set Port 11 bit 7 low                 */
    StartNewEvent();              /* Set Port 11 bit 7 high                */
    outp(PORT_8, 0x00);           /* Allow counter to be advanced by comp. */       (=00000000)
    temp = 0;
    
    for ( cell=0; cell<NUM_CELLS; cell++ ) {
	
	for ( chan=0; chan<NUM_CHAN; chan++ ) {
	    high = inp( PORT_10 ) & 0xF;  /* Read 4 high-order bits          */
	    v  = inp( PORT_9 );           /* Read SCA jig's 8 low-order bits */
	    v |= high << 8;               /* Combine high and low-order bits */
	    f = (double)v;                /* Convert integer to double       */
	    SCA[cell][chan] = f;
	    
	    if ((f< 5)||(f>4090))   temp += 1;  /* check if chan is bad 11-2-93*/
	    
	    if (temp > 20) {
		passedCrossTalk = FALSE;
		passedAllTests = FALSE;
		SetCtrlVal(Panel_PRD, PRD_CTLK_FAIL, ON );
		SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 2" );
		Fmt( result, "%s[a]<%s", "2C " );
	        cell = NUM_CELLS;
		chan = NUM_CHAN ;
		SetCtrlVal( Panel_PRD, PRD_CTLK_RUN,  OFF );
		return(0);
	    }
	    
	    outp(PORT_8, 0x01);           /* Inc Addr Cntr(Port 8 bit 0 high)*/      (=00000001)
	    outp(PORT_8, 0x00);           /* StrobeData (Port 8 bit 0 low)   */      (=00000000)
	}
    }
    
    return(0);
}


/*_ Read Cross Talk Data _________________________________________            This function is never called!
 *
 *  Function ReadCrossTalk reads the cross talk data from the Test
 *  Jig's memory.
 */

int ReadCrossTalk()
{
    double diff;
    double f;
    int cell, chan;   /* Loop indices */
    int v;
    int high;
    
    errNum = 0;                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );            /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    /*--------------------------------------------
     *  Read values from the SCA Test Jig's memory
     */
    outp(PORT_8, 0x01);           /* Allow counter to be advanced by comp. */      (=00000001)
    Mem_CompEnable();             /* Enable Jig to Computer data transfers */
    
    ClearCounters();              /* Set Port 11 bit 7 low                 */
    StartNewEvent();              /* Set Port 11 bit 7 high                */
    outp(PORT_8, 0x00);           /* Allow counter to be advanced by comp. */      (=00000000)
    
    for ( cell=0; cell<NUM_CELLS; cell++ ) {

	for ( chan=0; chan<NUM_CHAN; chan++ ) {
	    high = inp( PORT_10 ) & 0xF;  /* Read 4 high-order bits          */
	    v  = inp( PORT_9 );           /* Read SCA jig's 8 low-order bits */
	    v |= high << 8;               /* Combine high and low-order bits */
	    f = (double)v;                /* Convert integer to double       */
	    SCA[cell][chan] = f-SCA[cell][chan];
	    outp(PORT_8, 0x01);           /* Inc Addr Cntr(Port 8 bit 0 high)*/
	    outp(PORT_8, 0x00);           /* StrobeData (Port 8 bit 0 low)   */
	}
    }
    
    return(0);
}


/*_ Read Jig Memory __________________________________________
 *
 *  Function ReadJigMem reads the SCA Test Jig's memory, which
 *  ordinarily contains data read from the SCA chip.
 */

int ReadJigMem()
{
    double diff;
    double f;
    double v2;
    int cell, chan;   /* Loop indices */
    int v;
    int high;
    
    errNum = 0;                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );            /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    for ( chan=0; chan<NUM_CHAN; chan++ ) {
	SCA_chan[chan] = 0.0;         /* Clear mean/channel  */
	sigmaSCA_chan[chan] = 0.0;    /* Clear sigma/channel */
    }
    
    /*--------------------------------------------
     *  Read values from the SCA Test Jig's memory
     */
    outp(PORT_6, 0x03);          /* fee clear mem counter*/                       (=00000001)
    /*   outp(PORT_8, 0x01);    */       /* Allow counter to be advanced by comp. */
    Mem_CompEnable();             /* Enable Jig to Computer data transfers */     Port_6 = xxxxxx01
    
    /*   ClearCounters();   */          /* Set Port 11 bit 7 low                 */
    /*   StartNewEvent();   */           /* Set Port 11 bit 7 high                */
    outp(PORT_8, 0x00);           /* Allow counter to be advanced by comp. */     (=00000000)
    
    for ( cell=0; cell<NUM_CELLS; cell++ ) {
	
	for ( chan=0; chan<NUM_CHAN; chan++ ) {
	    high = inp( PORT_10 ) & 0xF;  /* Read 4 high-order bits          */
	    v  = inp( PORT_9 );           /* Read SCA jig's 8 low-order bits */
	    v |= high << 8;               /* Combine high and low-order bits */
	    f = (double)v;                /* Convert integer to double       */
	    SCA[cell][chan] = f;          /* Store                           */
	    outp(PORT_8, 0x01);           /* Inc Addr Cntr(Port 8 bit 0 high)*/     Are these two lines allright?
	    outp(PORT_8, 0x00);           /* StrobeData (Port 8 bit 0 low)   */     -----------------------------
	    v2 = f*f;                     /* Square                          */
	    SCA_chan[chan] += f;          /* Sum of value/channel matrix     */
	    sigmaSCA_chan[chan]  += v2;   /* Sum of value^2/channel matrix   */
	}
    }
    
    for ( chan=0; chan<NUM_CHAN; chan++ ) {
	SCA_chan[chan] /= NUM_CELLS;         /* Calculate mean/chan   */
	sigmaSCA_chan[chan] /= NUM_CELLS;    /* Calculate sigma/chan  */
	v2 = SCA_chan[chan]*SCA_chan[chan];
	diff = sigmaSCA_chan[chan] - v2;
	
	if ( diff <= 0.0 ) sigmaSCA_chan[chan] = 0.0;
      
	else sigmaSCA_chan[chan] = sqrt( diff );
    }
    
    return(0);
}


/*_ Read Sawtooth Data ________________________________________
 *
 *  Function ReadSawtooth reads the sawtooth data from the Test
 *  Jig's memory.
 */

int ReadSawtooth()
{
    double diff;
    double f;
    int handleHit;          /* For panel or menu bar event         */
    int itemSelected;       /* ID of control that caused the event */
    int cell, chan;         /* Loop indices                        */
    int v;
    int high,sca,data;
    char scaID[10];
    
    errNum = 0;                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );            /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    /*--------------------------------------------
     *  Read values from the SCA Test Jig's memory
     */
    
    for (sca=0;sca<NUM_SCA;sca++) {
	data = 0x80 | sca ;     /* set to read correspont SCA */
	outp(PORT_7, data);
	
	outp(PORT_8, 0x01);           /* Allow counter to be advanced by comp. */      (=00000001)
	Mem_CompEnable();             /* Enable Jig to Computer data transfers */
	
	ClearCounters();              /* Set Port 11 bit 7 low                 */
	StartNewEvent();              /* Set Port 11 bit 7 high                */
	outp(PORT_8, 0x00);           /* Allow counter to be advanced by comp. */      (=00000000)
	
	errNum = DeletePlots( Panel_SAW, SAW_DATA );
	
	errNum = HidePanel( Panel_PRD );
	/*  errNum = ClearGraphicsScreen( LT_GRAY );   */
	errNum = DisplayPanel( Panel_SAW );
	errNum = SetActivePanel( Panel_SAW );   /* Activate Panel_SAW         */
	Check_Err( WAIT );
	
	SetCtrlVal( Panel_SAW, SAW_SCA_ID, chipIDs );
	
	for ( cell=0; cell<NUM_CELLS; cell++ ) {
	    
	    for ( chan=0; chan<NUM_CHAN; chan++ ) {
		high = inp( PORT_10 ) & 0xF;  /* Read 4 high-order bits          */
		v  = inp( PORT_9 );           /* Read SCA jig's 8 low-order bits */
		v |= high << 8;               /* Combine high and low-order bits */
		f = (double)v;                /* Convert integer to double       */
		SCA[cell][chan] = f;
		outp(PORT_8, 0x01);           /* Inc Addr Cntr(Port 8 bit 0 high)*/
		outp(PORT_8, 0x00);           /* StrobeData (Port 8 bit 0 low)   */
	    }
	    
	    PlotStripChart( Panel_SAW, SAW_DATA, SCA, NUM_CHAN, cell*NUM_CHAN,0, 4 );
	}

	if (sca==0) {
	    
	    /* Wait for the user to select "GOOD IC" or "BAD IC" button */
	    
	    errNum = GetUserEvent( WAIT, &handleHit, &itemSelected );
	    Check_Err( WAIT );
	
	    if ( itemSelected == SAW_BAD_IC ) {
		sca = 1;
	    }
	    
	    /*  errNum = HitPanel_SAW( itemSelected );  */
	}
    }
    /* Wait for the user to select "GOOD IC" or "BAD IC" button */
    
    errNum = GetUserEvent( WAIT, &handleHit, &itemSelected );
    Check_Err( WAIT );
    
    errNum = HitPanel_SAW( itemSelected );
    
    return(0);
}


/*_ Run Calibration pulse ________________________________________
 *
 *  Function RunCal() pulse 16 channels of the selected SAS => SCA
 *
 */

int RunCal()
{
    int temp,sca,chan,new_chan,cell;
    int sas,sas_sin,sas_sin1,sas_sin2,data;
    int row_num,setting,complete;    /* for Gain calculation */    /*777*/      Does this 777 tell me something? It appears quite often.
    SetCtrlVal(Panel_PRD, PRD_LIN_RUN, ON );
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 0 );
    
    for ( setting = 0; setting <12 ; setting++)  /*777*/ {
	
        for ( chan = 0; chan<32 ;chan++) {
	    Cal_chan[setting][chan] = 0;       /* clear Cal_chan array */
	}
    }
    
    for ( setting = 0; setting <11 ; setting++)  /*777*/ {                   This line is not in "mpi_tes2.c".
	/*777*/
        complete =  100/10*setting ;                                            This will start at 0 (also 9% of the tests are done allready)!
        SetCtrlVal( Panel_PRD, PRD_PERCENT, complete );
	
	Set_SCA_Volts( voltSCA[setting] ); /*777*/     /* Sets SAS_VDC  */      Here the voltage is set!
	/*    Breakpoint ();  */

        for ( sca = 0; sca< NUM_SCA ;sca++) {                                NUM_SCA = 2

	    if ((sca == 0 )||(sca == 2)) {
		sas_sin1=0x80;    /* set SAS_SIN = LOW */                       What is the reason for these different bit settings?
		sas_sin2=0x88;    /* set SAS_SIN = HIGH */
	    }
	    
	    else {
		if ((sca == 1 )||(sca == 3)) {
		    sas_sin1=0x88;
		    sas_sin2=0x80;
		}
		
		else {                                   This will be executed if sca is not equal to 0,1,2 or 3!
		    sas_sin1=0x88;                       This is never the case!
		    sas_sin2=0x88;
		}
	    }
	    
	    /*  start clock in the selected SAS enable channels */
	    outp( PORT_6,0x03);   /* enable Side A for clocking GATED_CK1 & CK2 */      (=00000011) In "mpi_tes2.c" this is done only for sca == 0 or 1!
	    /*    outp( PORT_6,0x0B); */  /* enable card 0 for clocking GATED_CK1 & CK2 */  Otherwise (sca == 2 or 3) this line is executed in "mpi_tes2.c". 
	                                                                                        Also the comment reads "enable Side B for clocking..." in "mpi_tes2.c"
	    for (sas = 1;sas < 3 ;sas++) {

		for ( chan=0; chan<NUM_CHAN; chan++ ) {
		    
		    if ( sas == 1 ) sas_sin = sas_sin1;
		    
		    else sas_sin = sas_sin2;
		    
		    outp(PORT_7,sas_sin);     /* set SAS_SIN HIGH =0x88 */
		    outp(PORT_8,0x00);     /* clock CK1 LOW */                    (=00000000)
		    outp(PORT_8,0x02);     /* clock CK1 HIGH */                   (=00000010)
		    outp(PORT_8,0x00);     /* clock CK1 LOW */                    (=00000000)
		    outp(PORT_7,0x80);     /* clock CK2 LOW */                    (=10000000)
		    outp(PORT_7,0x90);     /* clock CK2 HIGH */                   (=10010000)
		    outp(PORT_7,0x80);     /* clock CK2 LOW */                    (=10000000)
		}
	    }
	    In "mpi_tes2.c" here is a additional line: "outp( PORT_6,0x0B);  /* reset P6-bit3 to allow all 4 SCAs to be read */". Do we need this?
	    if ( setting == 10 ) outp(PORT_7,0x80);          /* Disable calibration pulse to read Pedestal value */   (=10000000) This line is not in "mpi_tes2.c"
        
	    else outp(PORT_7,0x84);          /* Enable  calibration Pulse */                    (=10000100)
	    
	    errNum = SCA_DataAcq();     /* Move SCA chip data to jig memory    */
	    
	    data = 0x80 | sca ;    /* set to read correspont SCA & keep power ON */
	    outp(PORT_7, data);
	    
	    errNum = ReadJigMem();
	                            Everything after this line is new (in comparison to "mpi_tes2.c")!
	    for ( chan=0; chan<NUM_CHAN; chan++ ) {              NUM_CHAN = 16
		start = 16*sca ;
		new_chan = chan + start;
		
		for ( cell=255; cell<259; cell++ ) {
		    Cal_chan[setting][new_chan] = Cal_chan[setting][new_chan] + SCA[cell][chan];    
		}
		
		if ( setting == 0 )        /*777 to detect the Bad Cal channel */ {
		    
		    if ( ( Cal_chan[setting][new_chan] > 2100 )|| ( Cal_chan[setting][new_chan] < 700 )) {
			/*   if ( ( Cal_chan[setting][new_chan] > MAX_CAL_SUM )|| ( Cal_chan[setting][new_chan] < MIN_CAL_SUM  )) */
			passedCrossTalk = FALSE;
			passedAllTests = FALSE;
			SetCtrlVal(Panel_PRD, PRD_LIN_FAIL, ON );
			SetCtrlVal( Panel_PRD, PRD_PERCENT, 100 );
			SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 2CAL" );
			Fmt( result, "%s<%s", "2CAL" );
			return(0);
		    }
		}
	    }
	    
	    /*   if ( setting == 0 )
		 Breakpoint ();     */   
	}
    }
    
    /* to store Max & Min to row 10 & 11 */
    /* 777
       for ( chan=0; chan<NUM_CHAN_B; chan++ )
       {
       Cal_chan[10][chan] =  Cal_chan[0][chan]   ;
       Cal_chan[11][chan] =  Cal_chan[0][chan]   ;
       
       for ( setting = 0; setting <10 ; setting++)
       {
       
       if(Cal_chan[setting][chan] > Cal_chan[10][chan] )
       {
       Cal_chan[10][chan] =  Cal_chan[setting][chan]   ;
       }
       if(Cal_chan[setting][chan] < Cal_chan[11][chan] )
       {
       Cal_chan[11][chan] =  Cal_chan[setting][chan]   ;
       }
       }
       }
    */
    /*  Breakpoint ();  */
    
    errNum = RunLinearity();
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 0 );
    SetCtrlVal(Panel_PRD, PRD_LIN_RUN, OFF );
    return(0);
}


/*_ RUN CROSS TALK TEST _____________________________________________________      This function is never called!
 *
 *  Function RunCrossTalk runs the Functional Cross Talk test on the SCA chip.
 */

int RunCrossTalk()
     
{
    /*_Run Cross Talk test ____________________________
     */
    
    int numBadCells;     /* # Cells exceeding limit */
    
    testName = 1;        /* Functional test         */
    passedCrossTalk = TRUE;
    SetCtrlVal( Panel_PRD, PRD_CTLK_RUN,  ON );
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 0 );
    
    errNum = RunFuncTest( 3 );      /* Calculate un-pulsed baseline           */
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 50 );
    /* Breakpoint(); */
    
    errNum = RunFuncTest( 0 );      /* Calculate pulsed Cross Talk - baseline */
    /* Breakpoint(); */
    
    Check_Err( WAIT );
    numBadCells = CrossTalkValue(); /* Calculate # Cells exceeding limit      */
    /* Breakpoint(); */
    
    if ( numBadCells > max_Bad_Ctlk_Cells ) {
	passedCrossTalk = FALSE;
	passedAllTests = FALSE;
	SetCtrlVal(Panel_PRD, PRD_CTLK_FAIL, ON );
	SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 2" );
	Fmt( result, "%s<%s", "2C" );
    }
    
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 60 );
    return(0);
}


/*_ RUN CROSS TALK FEE TEST _____________________________________________________
 *
 *  Function RunCrossTalkFee runs the Functional Cross Talk test on the SCA chip.
 */

int RunCrossTalkFee()
     
{
    /*_Run Cross Talk test ____________________________
     */
    int turn,cell,chan;
    int numBadCells;     /* # Cells exceeding limit */
    
    passedCrossTalk = TRUE;
    SetCtrlVal( Panel_PRD, PRD_CTLK_RUN,  ON );
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 0 );
    
    for ( sca = 0; sca< NUM_SCA ;sca++) {                       In this function this sca-switch does nothing! 
                                                                (Only in the called CrossTalkValue() function it is used). 
                                                                How do we test both SCAs?
	Set_SCA_Volts( 0.00 );       /* Sets DC level voltage to  inputs */
	turn = -1;
	
	for ( turn = -1; turn <2 ;turn ++ ) {
	    outp( PORT_7, 0x88);    /* to clear input circuit shift register */                 PORT_8 = 10001000
	    outp( PORT_6, 0x08);    /* to read card 0 & set XILINX ready for new trigger */     PORT_6 = 00001000 - This line is missing in "mpi_tes2.c"!!!
	    outp( PORT_7, 0xA8);    /* to enable input circuit shift register */                PORT_7 = 10101000
	    outp( PORT_8, 0x04);    /* fee this enable memory clk of input circuit */           PORT_8 = 00000100
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    
	    errNum = ReadJigMem();
	    /*    errNum = ReadSelectSca();    */
	    
	    if (turn == 0 ) {                           Pedestal run.
		
		for ( cell=5; cell<NUM_CELLS; cell++ ) {
		    
		    for ( chan=0; chan<NUM_CHAN; chan++ ) {
			CrossTalkTemp[cell][chan] = SCA[cell][chan];
			
			if (( 20 > SCA_chan[chan])||(SCA_chan[chan] > 255)) {
			    /* Breakpoint(); */
			    passedAllTests = FALSE;
			    SetCtrlVal( Panel_PRD, PRD_CTLK_FAIL, ON );
			    SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 2" );
			    Fmt( result, "%s<%s", "2PEDES" );
			    SetCtrlVal( Panel_PRD, PRD_CTLK_RUN,  OFF );
			    
			    /* Breakpoint(); */
			    return(0);       /* any channels too low or too high pedestal */
			}
		    }
		}
		
		Set_SCA_Volts( 5.0 );       /* Sets DC level voltage to inputs */   Does this mean that there is no pulse injected?
	    }                     
          
	    else {                                                            This else comes also in effect for turn == -1. 
	                                                                   I don't think this was the intention (the loop for 
                                                                           turn == -1 was only added because of some hardware 
                                                                           (noise?) problem but this will not be solved by going through these steps!
		for ( cell=0; cell<NUM_CELLS; cell++ ) {
		    
		    for ( chan=0; chan<NUM_CHAN; chan++ ) {
			SCA[cell][chan] -= CrossTalkTemp[cell][chan];  /* substract CrossTalkTemp from SCA */
		    }
		}
	    }
	}
	
	errNum = CrossTalkValue();
	SetCtrlVal( Panel_PRD, PRD_PERCENT, 50 );
    }
    
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 0 );
    SetCtrlVal( Panel_PRD, PRD_CTLK_RUN,  OFF );
}


/*_ RUN DC TEST ____________________________________________
 *
 *  Function RunDcTest runs a single DC test on the SCA chip.
 */

int RunDcTest( testN )
     int testN;
{
    int i,chan;
    int muxSetting;               /* Tester DC out select 16-1 MUX   */
    int tmpmux;
    int oldp6;
    double adcTotal;
    int  max,bit,data,CK,ID;
    
    tmpmux = testN << 4;     /* Port 6 bits 7..4 select DC test */        (=ssss0000)
    oldp6 = (inp( PORT_6 ) & 0x0F );                                        (=0000xxxx)
    muxSetting = ( tmpmux | oldp6 ); 
    outp( PORT_6, muxSetting );          /* Select DC test                  */  (=ssssxxxx) This is different to "mpi_tes2.c" where PORT_6 = ssss0000!
    
    errNum = 0;                          /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    delay( 0.01 );                       /* Delay 0.01 seconds for MUX      */
    
    adcTotal = 0.0;
    
    for ( i=0; i<NUM_SAMPLES; i++ ) {                                    As in "mpi_tes2.c" nothing is done for testN = 4, 5, 6, 8, 10, 11, 13.
	errNum = AI_VRead( AIO_BD, CHAN_0, GAIN_1, &adcVolt[i] );
	Check_Err( WAIT );
	
	if ( testN == 0 )  adcVolt[i] *= 2.0;   /* Scale for +5v Ps divider */
	if ( testN == 1 )  adcVolt[i] *= 2.0;   /* Scale for -5v Ps divider */
	if ( testN == 2 )  adcVolt[i] *= 1;   /* Scale for +5v current    */
	if ( testN == 3 )  adcVolt[i] *= 1;   /* Scale for -5v current    */
	/* 7777 */
	
	if (( testN == 7 )||( testN == 9 ))  /* SAS Sout bit */ {           Why has this part to stay in the for loop? It will be executed 10 times!
	    outp( PORT_6,0xE0);   /* SET fee OUTPUT ENABLE */               PORT_6 = 11100000, why not 11100011 (see in a few lines)?

	    /*  start clock in the selected SAS enable channels */
          
	    if ( testN == 7) {
		outp( PORT_6,0x73);   /* enable Side A for clocking GATED_CK1 & CK2 */   (=01110011)
	    }
	                                                                                    Are these two settings allright?
	    if ( testN == 9)   {
		outp( PORT_6,0x9B);   /* enable Side B for clocking GATED_CK1 & CK2 */   (=10011011)
	    }
	}
        
	for ( chan=0; chan<32; chan++ )     {                            This loop is invoked for every test!! This makes no sense! 
                                                                            May be it has to stay between the last pair of braces?
	    data = 0x88;
	    outp(PORT_7,data);     /* set SAS_SIN HIGH =0x88 */
	    outp(PORT_8,0x00);     /* clock CK1 LOW */                    (=00000000)
	    outp(PORT_8,0x02);     /* clock CK1 HIGH */                   (=00000010)
	    outp(PORT_8,0x00);     /* clock CK1 LOW */                    (=00000000)
	    outp(PORT_7,0x80);     /* clock CK2 LOW */                    (=10000000)
	    outp(PORT_7,0x90);     /* clock CK2 HIGH */                   (=10010000)
	    outp(PORT_7,0x80);     /* clock CK2 LOW */                    (=10000000)
	}
	
	if ( testN == 12) {                                                 What is this for? It is never set to 0.0 or whatever!
	    Set_SCA_Volts( -4.3); /* Sets DC level voltage to SCA inputs */ In "mpi_tes2.c" the value is -3.8.
	}
	
	if (( testN == 14 )||( testN == 15 ))  /* geometric ID */ {
	    outp( PORT_6,0xE3);   /* SET FTPC fee OUTPUT ENABLE */          PORT_6 = 11100011 why not 11100000 (see a few lines above)
	    /*  outp(PORT_7,0X90);   */  /* set clock CK2 High */
	    
	    delay (0.1);
	    /* 7777  */
            ID = inp ( PORT_9 );   /*  read board ID data */
            adcVolt[i] = 0.01*ID;
	    outp(PORT_7,0x80);     /* fee clear the select pulsed channels Shift register */   In "mpi_tes2.c" this line is placed after "adcTotal += adcVolt[i];" (below).
                                                                                                Here it means that it will be invoked only for testN = 14 or 15 (which are excluded in the moment)! 
	}
	
	adcTotal += adcVolt[i];
    }
    
    adcMean = adcTotal / NUM_SAMPLES;
    adcSigma = Sigma( adcVolt, adcMean );
        
    dcTestResult = adcMean;                                                  These three line are not in "mpi_tes2.c"!
    muxSetting = ( 0xF0 & oldp6 );                                       This sets PORT_6 = 00000000!
    outp( PORT_6, muxSetting );          /* Select unconnected mux input */  I think it should read "muxSetting = ( 0x0F & oldp6 );".
    
    return(0);
}


/*_ RUN DC TESTS _______________________________________
 *
 *  Function RunDcTests runs 16 DC tests on the SCA chip.
 */

int RunDcTests()
{
    /*_ Run DC tests ___________________________________
     */
    int test;              /* Index over test numbers */
    int complete;
    
    testName = 0;          /* DC test                 */
    passedDCTests = TRUE;
    SetCtrlVal( Panel_PRD, PRD_DC_RUN,  ON );
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 0 );
    
    for ( test=0; test<NUM_TESTS_DC-2; test++ ) {               No ID tests in the moment...why?
	/* changed to ..._DC-2; for debugging */
	/* has to be ..._DC; */
	
	/*------------------------------------
	 *  Special setup to read the Voltage at the SCA output
	 */
	
	if((test == 10) || (test == 11)) {
	    /* set DC voltage to 3.4 V */
	    errNum = SelectAllChanels();     /* Select all 16 SCA 1 channels */       (PORT_7 = xxxxxx11)
	    errNum = SelDCsig();             /* Select DC signal inject into SCA */   (PORT_6 = xxxx10xx)
	    Set_SCA_Volts( voltSCA[0] );     /* Set DC voltage level to 3.4 V */      No! The voltage is set to -3.9 V (=voltSCA[0])!
	    delay(0.1);
	}
	
	if((test == 12) || (test == 13)) {
	    /* set DC voltage to 1.6 V */
	    errNum = SelectAllChanels();     /* Select all 16 SCA 1 channels */        (PORT_7 = xxxxxx11)
	    errNum = SelDCsig();             /* Select DC signal inject into SCA */    (PORT_6 = xxxx10xx)
	    Set_SCA_Volts( voltSCA[9] );     /* Set DC voltage level to 1.6 V */       No! The voltage is set to -4.7 V (=voltSCA[0])!
	    delay(0.1);
	}
	
	errNum = RunDcTest( test );  /* Run test */
	boundsDC[test][1] = dcTestResult;
	
	Check_Err( WAIT );
	/* update % complete display */
	complete =  100 - ( ( NUM_TESTS_DC - test ) * (100/NUM_TESTS_DC) );
	SetCtrlVal( Panel_PRD, PRD_PERCENT, complete );
	/*    Breakpoint ();    */
	
	/* display result in user panel */
	
	if ( ((boundsDC[test][0] > boundsDC[test][1])  ||
	      (boundsDC[test][1] > boundsDC[test][2]))  &&
	     (test < 16 )) {
	    passedAllTests = FALSE;
	    SetCtrlVal( Panel_PRD, PRD_DC_FAIL, ON );
	    SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 1" );
	    
	    Fmt( result, "%s<%s", "1" );
	    test = 16;      /* to stop the DC test */
	}
    }
    
    SetCtrlVal( Panel_PRD, PRD_DC_RUN,  OFF );
    return(0);
}


/*_ RUN FUNC TEST ____________________________________________________
 *
 *  Function RunFuncTest runs a single Functional test on the SCA Chip.
 */

int RunFuncTest( testNum )
     int testNum;
     
{
    int cell, chan;  /* Loop indices */
    int pattern;     /* Test pattern */
    
    errNum = 0;                     /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );              /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    switch ( testNum )
	{
	    
	case 0:
	    /* Check cross talk between channels when injecting a non-overlapping   */
	    /* in time pulses to all 16 channels.  The graphical display shows      */
	    /* the cross talk.                                                      */
	    errNum = WalkingPulse();     /* Non-overlapping pulses all channels  */
	    errNum = SelDCsigOddEven();  /* Select DC signal inject into SCA         */
	    Set_SCA_Volts( 5.00 );       /* Sets DC level voltage to SCA inputs      */
	    outp( PORT_7, 0xA8);    /* to enable input circuit shift register */             (=10101000)
	    outp( PORT_8, 0x04);    /* fee this enable memory clk of input circuit */        (=00000100)
	    delay(1.0);
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory         */
	    /*    errNum = ReadCrossTalk();  */
	    
	    /*   data = 0x80 | sca ; */   /* set to read correspont SCA & keep power ON */
	    /*   outp(PORT_7, data); */
	    /*     outp(PORT_7, 0x80);  */
	    errNum = ReadJigMem();
	    /* Breakpoint(); */
	    break;

	case 1:
	    errNum = WalkingPulse();     /* Non-overlapping pulses all channels */
	    errNum = SelDCsigOddEven();  /* Select DC into odd/even SCA cells   */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    Set_SCA_Volts( 1.84 ); /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    break;
	    
	case 2:
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[9] );/* Sets DC level voltage to SCA inputs */
	    /* 3/19/96 the following function SCA_DataAcq() is needed because for */
	    /* some reason if we run the Sigma test alone (case 2) then the */
	    /* noise is low ~the first 16 T.Bs then go up 4 times in the rest of T.B*/
	    errNum = SCA_DataAcq();     /* Move SCA chip data to jig memory         */
	    delay (2.0); /* add in 5/16/94 to allow for electronic to stabilize */
	    errNum = MeasurePedestal();
	    break;
	    
	case 3:
	    /* Read baseline data with no pulsing for cross talk comparison.   */
	    /* Same logic as case 0, except there is no Walking Pulse.         */
	    /*      errNum = SelDCsigOddEven();*/ /* Select DC signal inject into SCA    */
	    /* P_T4 for some reason the next 2 statement is important --check what it does */
	    errNum = WalkingPulse();     /* Non-overlapping pulses all channels  */
	    errNum = SelDCsigOddEven();   /* Select DC signal inject into SCA         */
	    
	    Set_SCA_Volts( 0.00 );    /* Sets DC level voltage to  inputs */
	    outp( PORT_7, 0xA8);    /* to enable input circuit shift register */            (=10101000)
	    outp( PORT_8, 0x04);    /* fee this enable memory clk of input circuit */       (=00000100)
	    /* Breakpoint(); */
	    
	    errNum = SCA_DataAcq();     /* Move SCA chip data to jig memory    */
	    /*    errNum = ReadCrossTalk0();  */
	    /*    outp(PORT_7, 0x80);    */
	    errNum = ReadJigMem();
	    
	    /* Breakpoint(); */
	    
	    break;
	    
	default: break;
	}
    
    return(0);
}


/*_ RUN GLITCHES ON BASELINE TEST _______________________________________________
 *
 *  Function RunGlitchBaseline runs the Glitches on Baseline test on the SCA chip.
 */

int RunGlitchBaseline()
     
{
    /*_Run Glitches on Baseline ____________________________
     */
    
    int cell, chan;      /* Loop indices            */
    int numBadCells;     /* # Cells exceeding limit */
    
    testName = 1;        /* Functional test         */
    passedGlitchTest = TRUE;
    SetCtrlVal( Panel_PRD, PRD_GLITCH_RUN,  ON );
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 0 );
    
    numBadCells = GlitchValue(); /* Calculate # Cells exceeding limit      */
    
    if ( numBadCells > max_Bad_Glitch_Cells ) {
	passedGlitchTest = FALSE;
	passedAllTests = FALSE;
	SetCtrlVal(Panel_PRD, PRD_GLITCH_FAIL, ON );
      SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 5" );
      State = 5;
      Fmt( result, "%s<%s", "5" );
    }
    
    /*   SetCtrlVal( Panel_PRD, PRD_PERCENT,100 );  */
    SetCtrlVal( Panel_PRD, PRD_GLITCH_RUN,  OFF );
   
    return(0);
}


/*_ RUN LINEARITY TEST ___________________________________________
 *
 *  Function RunLinearity runs the Linearity tests on the SCA chip.
 */

int RunLinearity()
     
{
    /*_ Run Linearity Tests _______________________________
     */
    char   temp[40];
    double gain,resistance;
    double slope,min,d_gain;
    int    chan, i,R,row;           /* Loop indices            */
    double linearityMeasure;  /* # Cells exceeding limit */
    
    testName = 1;             /* Functional test         */
    passedLinearityTest = TRUE;
    SetCtrlVal( Panel_PRD, PRD_LIN_RUN,  ON );
    
    for ( i=0; i<NUM_LIN; i++ ) {           NUM_LIN = 10 (number of linearity tests)
	/*    RunParamTest( i );
	      Mean( SCA_chan, NUM_CHAN, &m[i][0] );
	*/
	
	for ( chan=0; chan<NUM_CHAN_B; chan++ ) {         NUM_CHAN_B = 32 (to calculate linearity for both 16 channel SCA chips)
	    m[i][chan] = Cal_chan[i][chan] - Cal_chan[10][chan]; /* store Ped sub data */
	}
    }
    
    /* RunParamTest( i );  Run linearity test i   */
    /* m[i][chan] = SCA_chan[chan];  Save mean/channel calculations */
    Transpose( B, 10, 2, BT );                   /* Transpose matrix B          */     I hope this is done right.
    MatrixMul( BT, B, 2, 10, 2, BTB );           /* Matrix product, BT x B      */     
    InvMatrix( BTB, 2, invBTB );                 /* Compute matrix inverse      */
    MatrixMul( invBTB, BT, 2, 2, 10, invBTB_BT );/* Matrix product              */
    
    /* Solve the overdetermined matrix equation "m = B x c" for a least */
    /* squares estimate of the unknown linearity coefficients c, which  */
    /* are the offset and gain for each SCA channel.                    */
    
    MatrixMul( invBTB_BT, m, 2, 10, NUM_CHAN_B, c ); /* Solve for unknown */
    MatrixMul( B, c, 10, 2, NUM_CHAN_B, fit );       /* Solve for fit     */
    Sub2D( m, fit, 10, NUM_CHAN_B, fitDiff );        /* Fit error         */

    for ( row=0; row<10 ;row++) {
	
	for ( chan=0; chan<NUM_CHAN_B; chan++ ) {
	    /*  Percent_fitDiff[row][chan] = fitDiff[row][chan]*100/fit[row][chan]; */
	    fitDiff[row][chan] = fitDiff[row][chan]*100/fit[row][chan];
	}
    }
    
    for ( chan=0; chan<NUM_CHAN_B; chan++ ) {
	linearityMeasure = LinearityValue( chan );/* Calc Linearity measure */
	maxNonLin[chan] = linearityMeasure;
	/*   if (( linearityMeasure > max_Linearity_Diff ) ||
	     ( c[1][chan] < min_Gain ) ||
	     ( c[1][chan] > max_Gain ))      */
	
	if (( linearityMeasure > 10 ) ||
	    ( c[1][chan] < 400 ) ||
	    ( c[1][chan] > 1500 )) {
	    /*  Breakpoint ();   */
	    
	    passedLinearityTest = FALSE;
	    passedAllTests = FALSE;
	    SetCtrlVal(Panel_PRD, PRD_LIN_FAIL, ON );
	    SetCtrlVal( Panel_PRD, PRD_TEST_RESULT, "FAILED: Put IC into Box 3" );
	}
    }
    
    /*      Breakpoint ();      */
    if( ! passedLinearityTest ) {
	Fmt( result, "%s<%s", "3" );
    }
    
    SetCtrlVal( Panel_PRD, PRD_TEST_RESULT, temp );
    SetCtrlVal( Panel_PRD, PRD_PERCENT,100 );
    SetCtrlVal( Panel_PRD, PRD_LIN_RUN,  OFF );
    
    return(0);
}

/*_ RUN PARAM TEST ____________________________________________________
 *
 *  Function RunParamTest runs a single Parametric test on the SCA chip.
 */

int RunParamTest( testNum )
     int testNum;
     
{
    int complete;
    int i;
    
    double adcTotal;
    
    errNum = 0;                    /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );             /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    complete = testNum * 10;
    SetCtrlVal( Panel_PRD, PRD_PERCENT, complete );
    
    switch ( testNum )
	{
	    
	case 0:
	    /* Linearity sample of all cells for DC voltage 3.4 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[0] );    /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[0][1] = dcTestResult;
	    break;
	    
	case 1:
	    /* Linearity sample of all cells for DC voltage 3.2 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[1] );    /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[1][1] = dcTestResult;
	    break;
	    
	case 2:
	    /* Linearity sample of all cells for DC voltage 3.2 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[2] );    /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[2][1] = dcTestResult;
	    break;
	    
	case 3:
	    /* Linearity sample of all cells for DC voltage 2.8 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[3] );    /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[3][1] = dcTestResult;
	    break;
	    
	case 4:
	    /* Linearity sample of all cells for DC voltage 2.6 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[4] ); /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[4][1] = dcTestResult;
	    break;
	    
	case 5:
	    /* Linearity sample of all cells for DC voltage 2.4 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[5] );    /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[5][1] = dcTestResult;
	    break;
	    
	case 6:
	    /* Linearity sample of all cells for DC voltage 2.2 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[6] );    /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[6][1] = dcTestResult;
	    break;
	    
	case 7:
	    /* Linearity sample of all cells for DC voltage 2.0 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[7] );    /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[7][1] = dcTestResult;
	    break;
	    
	case 8:
	    /* Linearity sample of all cells for DC voltage 1.8 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[8] );    /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[8][1] = dcTestResult;
	    break;
	    
	case 9:
	    /* Linearity sample of all cells for DC voltage 1.6 */
	    errNum = SelectAllChanels(); /* Select all 16 channels of SCA       */
	    errNum = SelDCsig();         /* Select DC signal inject into SCA    */
	    Set_SCA_Volts( voltSCA[9] );    /* Sets DC level voltage to SCA inputs */
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadJigMem();
	    RunDcTest(11);   /* Connect CH0 input to ADC input */
	    B[9][1] = dcTestResult;
	    break;
	    
	case 10:
	    /* Pulse all channels with a time varying sawtooth wave.  The       */
	    /* graphical display shows the cross talk.                          */
	    Set_SCA_Volts( voltSCA[5] );    /* Sets DC level voltage to SCA inputs */
	    /*   errNum = SelectAllChanels(); */ /* Select all 16 channels of SCA       */   Where is the pulse injected
	    /*   errNum = SelTriangSig();  */   /* Select triangular signal into SCA   */    if not here?
	    errNum = SCA_DataAcq();      /* Move SCA chip data to jig memory    */
	    errNum = ReadSawtooth();
	    break;
	    
	default: break;
	}
    
    return(0);
}


/*_ RUN SAWTOOTH TEST ____________________________________________________
 *
 *  Function RunSawTooth runs one Sawtooth Parametric test on the SCA chip.
 */

int RunSawTooth()
     
{
    /*_Run Sawtooth Parametric test ______________________________
     */
    
    testName = 2;            /* Parametric test         */
    passedSawToothTest = TRUE;
    SetCtrlVal( Panel_PRD, PRD_SAW_RUN, ON );
    
    errNum = RunParamTest( 10 );   /* Run Sawtooth test */
    
    /* WARNING:  Program control is interupted at this point. */    This means that the test has to be done by eye!
    /* Subsequent program flow depends on which button ( e.g. */
    /* "GOOD IC", "BAD IC", or "Home") the user selects from  */
    /* the Sawtooth Panel.                                    */
    
    return(0);
}


/*_ RUN SIGMA OF PEDESTAL TEST ______________________________________________
 *
 *  Function RunSigmaPedestal runs the Sigma of Pedestal test on the SCA chip.
 */

int RunSigmaPedestal()
     
{
    /*_Run Sigma of Pedestal ____________________________
     */
    
    int numBadCells;     /* # Cells exceeding limit */
    int chan;
    
    testName = 1;        /* Functional test         */
    passedSigmaPedestal = TRUE;
    SetCtrlVal( Panel_PRD, PRD_SIGMA_RUN,  ON );
    
    for ( chan=0; chan<NUM_CHAN_B; chan++ ) {                           NUM_CHAN_B = 32
	SCAo_chan[chan] = 0.0;          /* Clear Pedestal mean/channel  */
	sigmaSCAo_chan[chan] = 0.0;     /* Clear Pedestal sigma/channel */
    }
    
    for (sca=0;sca<NUM_SCA;sca++) {                                     NUM_SCA = 2
	errNum = RunFuncTest( 2 );      /* Calculate Sigma of Pedestal */
	Check_Err( WAIT );
	numBadCells = SigmaPedestalValue(); /* Calculate # Cells exceeding limit      */
	
	if ( numBadCells > max_Bad_Sigma_Cells ) {
	    passedSigmaPedestal = FALSE;
	    passedAllTests = FALSE;
	    SetCtrlVal(Panel_PRD, PRD_SIGMA_FAIL, ON );
	    SetCtrlVal( Panel_PRD, PRD_TEST_RESULT  , "FAILED: Put IC into Box 4" );
	    Fmt( result, "%s<%s", "4" );
	    return(0);
	}
    }
    
    SetCtrlVal( Panel_PRD, PRD_PERCENT, 100 );
    SetCtrlVal( Panel_PRD, PRD_SIGMA_RUN,  OFF );
    
    return(0);
}

/*_ Save Test Data _________________________________
 *
 *  Function SaveTestData writes selected test results from arrays to a disk file.
 */

int SaveTestData()
     
{
    int testValue;
    int numBytes;
    char testData[4096];
    
    dataLogFile = OpenFile( dataFileName, WRITE_ONLY, APPEND, ASCII );
    
    Fmt( testData, "%s[w7]<%s\t", chipIDs );
    Fmt( testData, "%s[a]<%s\t", datestr() );
    Fmt( testData, "%s[w9a]<%s\t", timestr() );
    Fmt( testData, "%s[a]<%s\t", result );
    Fmt( testData, "%s[a]<%s\t", operatorName );
    
    for( testValue=0; testValue<NUM_TESTS_DC; testValue++ ) {
	Fmt( testData, "%s[a]<%f[p3]\t", boundsDC[testValue][1] );
    }
 
    for( testValue=0; testValue<NUM_CHAN_B; testValue++ ) {
	Fmt( testData, "%s[a]<%f[p0]\t", PulseChanSum[testValue] );
    }
    
    for( testValue=0; testValue<NUM_CHAN_B; testValue++ ) {
        Fmt( testData, "%s[a]<%d\t", chanCrsTlk[testValue] );
    }
    
    for( testValue=0; testValue<NUM_CHAN_B; testValue++ ) {
	Fmt( testData, "%s[a]<%d\t", chanMaxCtlk[testValue] );
    }

    for( testValue=0; testValue<NUM_CHAN_B; testValue++ ) {
	Fmt( testData, "%s[a]<%f[p0]\t", m[0][testValue] );  /*777*/
    }
    
    /*   for( testValue=0; testValue<NUM_CHAN; testValue++ )
         {
	 Fmt( testData, "%s[a]<%d\t", ChanMaxJump[testValue] );
         }                */   /* stop save ChanMaxJump */
    /*   for( testValue=0; testValue<NUM_CHAN; testValue++ )
         {
	 Fmt( testData, "%s[a]<%f[p0]\t", c[1][testValue] );
         }                 */
    
    for( testValue=0; testValue<NUM_CHAN_B; testValue++ ) {
	Fmt( testData, "%s[a]<%f[p3]\t", maxNonLin[testValue] );
    }
    
    for( testValue=0; testValue<NUM_CHAN_B; testValue++ ) {
        Fmt( testData, "%s[a]<%f[p3]\t", sigmaSCAo_chan[testValue] );
    }
   
    for( testValue=0; testValue<NUM_CHAN_B; testValue++ ) {
        Fmt( testData, "%s[a]<%d\t", glitch_Num[testValue] );
    }
   
    Fmt( testData, "%s[w1a]<%s[w1]\n", ";" );
    
    numBytes = WriteLine( dataLogFile, testData, -1 );
    CloseFile(dataLogFile);
}


/*_ SCA Data Acquisition _________________________________
 *
 *  Function SCA_DataAcq moves SCA chip data to jig memory.
 */

int SCA_DataAcq()
{
    int new,old,temp;
    errNum = 0;                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );            /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    /*------------------------------------------------
     *  Read values from SCA chip to Test Jig's memory
     */
    
    if ( testDataOn ) SCA_MemTest();             /* Enable Test Data to jig mem transfers */  PORT_6 = xxxxxx11
    
    else SCA_MemEnable();           /* Enable SCA to jig mem data transfers  */               PORT_8 = 0000xxx0
    
    StrobeData();                 /* Set Port  8 bit 0 low                 */                 The former indentation implies that this should be done only for the else case. What is true?
    outp(PORT_6,0x08);            /*  */                                                      PORT_6 = 00001000, missing in "mpi_tes2.c"
    old = inp(PORT_7);            /* fee read port's old value     */
    new = (old & 0xFC);           /* fee set bit ..1.0 to zero     */
    outp(PORT_7,new) ;            /*    to allow a13,a14 switching */                         PORT_7 = xxxxxx00, in "mpi_tes2.c" it is set to xxxxxx0x! Which one is false?
    ClearCounters();              /* Set Port 11 bit 7 low         */                         PORT_11 = 0
    /*Breakpoint ();*/
    delay(1.0);            /* P_T4 this delay is IMPORTANT for test board stable before trigger */
    StartNewEvent();              /* Set Port 11 bit 7 high                */                 PORT_11 = 10000000, Trigger
    errNum = TestJigStatus();     /* Wait for zero status(-1 ==> error)    */
    Check_Err( WAIT );
    return(0);
}


/*_ SCA Chip to Jig Memory Enable _________________________________
 *
 *  Function SCA_MemEnable enables SCA chip to jig memory transfers.
 */

int SCA_MemEnable()
{
    int new, old;
    
    old = inp( PORT_6 );      /* Read port's old value                    */
    new = (old & 0xFC) ;  /* Set bits 1..0 to 1.1                    */         No! They are set to 0.0
    outp( PORT_6, new );      /* Enables SCA chip to jig memory transfers */        PORT_6 = xxxxxx00, in "mpi_tes2.c" this reads = 00001000!
    return(0);
}


/*_ SCA Test Data to Jig Memory Enable _________________________________
 *
 *  Function SCA_MemTest enables SCA Test Data to jig memory transfers.
 */

int SCA_MemTest()
{
    int new, old;
    
    old = inp( PORT_6 );       /* Read port's old value                    */
    new = (old & 0xFC) | 0x3;  /* Set bits 1..0 to 1,1                     */
    outp( PORT_6, new );       /* Enables SCA chip to jig memory transfers */       (=xxxxxx11)
    return(0);
}


/*_ Select DC Signal Into SCA Chip _______________________________
 *
 *  Function SelDCsig Selects DC signal into SCA chip.
 */

int SelDCsig()
{
    int new, old;
    
    old = inp( PORT_6 );       /* Read port's old value          */
    new = (old & 0xF3) | 0x8;  /* Set bits 3..2 to 1,0           */
    outp( PORT_6, new );       /* Select DC signal into SCA chip */            (=xxxx10xx)
    return(0);
}


/*_ Select DC Signal Into Odd/Even SCA Cells _________________________        This function is never called!
 *
 *  Function SelDCsigOddEven Selects DC signal into odd/even SCA cells.
 */

int SelDCsigOddEven()
{
    int new, old;
    
    old = inp( PORT_6 );       /* Read port's old value                    */
    new = (old & 0xF3) | 0xC;  /* Set bits 3..2 to 1,1                     */
    outp( PORT_6, new );       /* Select DC signal into odd/even SCA cells */  (=xxxx11xx)
    return(0);
}


/*_ Select all 16 Input Channels of SCA Chip __________________________
 *
 *  Function SelectAllChanels selects all 16 input channels of SCA chip.
 */

int SelectAllChanels()
{
    int new, old;
    
    old = inp( PORT_7 );       /* Read port's old value                    */
    new = (old & 0xFC) | 0x03; /* Set bits 1..0 to 1,1                     */
    outp( PORT_7, new );       /* Select all 16 input channels of SCA chip */  (=xxxxxx11)
    return(0);
}


/*_ Select External Signal Into SCA Chip _______________________________
 *
 *  Function SelExtsig Selects External signal into SCA chip.
 */

int SelExtsig()                                                         This function is never called!
{
    int new, old;
    
    old = inp( PORT_6 );       /* Read port's old value          */
    new = (old & 0xF3) | 0x4;  /* Set bits 3..2 to 0,1           */
    outp( PORT_6, new );       /* Select Ext signal into SCA chip */            (=xxxx01xx)
    return(0);
}



/*_ Select Triangular Signal into SCA Chip ____________________________       This function is never called (but it should -> sawtooth test)!
 *
 *  Function SelTriangSig selects a triangular signal into the SCA chip.
 */

int SelTriangSig()
{
    outp( PORT_6, 0x00 );  /* Select triangular signal into the SCA */          (=00000000)
    return(0);
}


/*____________________________________
 *
 * Sets DC level voltage to SCA inputs.
 */
int Set_SCA_Volts( DACvolts )
double DACvolts;
{
    dacVolts = DACvolts;
    errNum = AO_VWrite( AIO_BD, CHAN_1, DACvolts );
   
    if ( DACvolts > 0.1 ) delay( 0.5 );     /* Delay 0.5 seconds to let voltage stabilize */
    
    if (errNum < 0) {
	Fmt( errStr, "%s", "Set_SCA_Volts()" );
	return(-1);
    }
    
   return(0);
}


/*_ Sigma Pedestal Value _____________________________________________
 *
 *  Function SigmaPedestalValue counts excessive sigma pedestal values.
 */

int SigmaPedestalValue()
{
    int cell, chan;   /* Loop indices */
    int value;
    
    errNum = 0;                   /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_NUM, errNum );
    Fmt( errStr, "" );            /* Clear previous error indication */
    SetCtrlVal( Panel_PRD, PRD_ERR_STR, errStr );
    
    value = 0;
    
    for ( chan=0; chan<NUM_CHAN; chan++ ) {
	
      for ( cell=10; cell<NUM_CELLS; cell++ ) {
	  
	  if ( sigmaSCAo[cell][chan] > max_Sigma_Counts )                   max_Sigma_Counts is read from fileLimits.
	      value += 1;     /* Count occurences of excessive cross talk */
      }
    }
    
    return( value );
}


/*_ Start New Event ______________________________________________
 *
 *  Function StartNewEvent sets the SCA trigger hign.  This starts
 *  the new event.
 */

int StartNewEvent()
{
    outp(PORT_11, 0x80);  /* Set bit 7 of Port 11 high */                  (=10000000)
    return(0);
}


/*_ Strobe Data __________________________________________________
 *
 *  Function StrobeData sets the SCA trigger low.  This clears all
 *  counters on the test jig and prepares it for the new event.
 */

int StrobeData()
{
    int old,new;
    old = inp(PORT_8);            /* fee read port's old value */
    new = (old&0x0E);           /* fee set bit ..0 to zero */
    outp(PORT_8,new) ;            /*     to allow address counter run */   (=0000xxx0)
    
    /*  outp(PORT_8, 0x00); */ /* Set bit 0 of Port 8 low */
    return(0);
}


/*_ Test Jig Status ________________________________________________
 *
 *  Function TestJigStatus reads test jig status and re-tries until
 *  either a non zero status is obtained or it times out.  0 ==>
 *  ready.
 */

int TestJigStatus()
{
    int iteration;  /* Tries to get non-zero status */
    int status;     /* Status of the test jig.      */
    
    for ( iteration=0; iteration<MAX_TRY_STATUS; iteration++ ) {
	status = inp(PORT_10) & 0x80;   /* Mask off bit-7 */
	
	if( status == 0 )  return( 0 );
    }
    
    errNum = -1;
    Fmt( errStr, "%s", "Timeout - Jig Status" );
    return(-1);      /* Test Jig Status Timeout error */
}


/*_ Non-overlapping pulses on all 16 SCA Input Channels __________            This function is never called!
 *
 *  Function WalkingPulse selects non-overlapping SCA input pulses.
 */

int WalkingPulse()
{
    int new, old;
    
    old = inp( PORT_7 );       /* Read port's old value                    */
    new = (old & 0xF8) | 0x04; /* Set bits 2..0 to 1,0,0                   */
    outp( PORT_7, new );       /* Select all 16 input channels of SCA chip */            (=xxxxx100)
    return(0);
}


/*~ COMMON FUNCTIONS ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 * The following common functions interface with National Instrument's
 * Graphical User Interface and I/O cards that drive LBL's IC Tester
 * Hardware for PA-4, PA-16, SA-16, PASA, and SCA ICs.  These functions
 * run under Lab Windows C, which does not support User Libraries.
 */


/*_______________________________________________________
 *
 * Update error status displays, if an error has occured.
 */
void Check_Err( wait )
     int wait;
{
    int numBytes;  /* Number of bytes written */
    
    if (errNum < 0) {
	errCount++;
	SetCtrlVal( Panel_PRD, PRD_ERR_NUM  , errNum   );
	SetCtrlVal( Panel_PRD, PRD_ERR_STR  , errStr   );
	RingBell( 2 );
	Fmt( newError, "%s[w16]<%s\t" , "Error         " );
	Fmt( newError, "%s[w16a]<%s\t", "Fatal         " );
	Fmt( newError, "%s[a]<%i\t"   , errNum    );
	Fmt( newError, "%s[w25a]<%s\t", errStr    );
	Fmt( newError, "%s[w11a]<%s\t", datestr() );
	Fmt( newError, "%s[w8a]<%s\n" , timestr() );
	numBytes = WriteLine( errorLogFile, newError, -1 ); /* Log error */
	errNum = 0;                   /* Clear previous error indication */
	Fmt( errStr,  "" );           /* Clear previous error indication */
	
	if ( wait ) {
	    /* Generate a Pop-up "Do you want to proceed? */
	}
    }
}


/*______________________________________________
 *
 * Clear the PC-DIO-96 board's ports 0..8 and 11.
 */
int DIO_Clear()
{
    outp(PORT_0,0);   /* Clear DIO Port  0 */
    outp(PORT_1,0);   /* Clear DIO Port  1 */
    outp(PORT_2,0);   /* Clear DIO Port  2 */
    outp(PORT_3,0);   /* Clear DIO Port  3 */
    outp(PORT_4,0);   /* Clear DIO Port  4 */
    outp(PORT_5,0);   /* Clear DIO Port  5 */
    
    outp(PORT_6,0);   /* Clear DIO Port  6 */
    outp(PORT_7,0);   /* Clear DIO Port  7 */
    outp(PORT_8,0);   /* Clear DIO Port  8 */
    
    outp(PORT_11,0);  /* Clear DIO Port 11 */
    
    return(0);
}


/*__________________________________________________________
 *
 * Init the PC-DIO-96 board so ports 0..8 and 11 are outputs.
 * Ports 9 and 10 (bits 0..3) are bi-directional data bus.
 * Port 10 (bits 4..7) are input only.
 */
int DIO_Init()
{
   int i;

   errNum += DIG_Prt_Config(DIO_BD,  0, DIO_NO_HNDSHK, DIO_DIR_OUT);
   errNum += DIG_Prt_Config(DIO_BD,  1, DIO_NO_HNDSHK, DIO_DIR_OUT);
   errNum += DIG_Prt_Config(DIO_BD,  2, DIO_NO_HNDSHK, DIO_DIR_OUT);
   errNum += DIG_Prt_Config(DIO_BD,  3, DIO_NO_HNDSHK, DIO_DIR_OUT);
   errNum += DIG_Prt_Config(DIO_BD,  4, DIO_NO_HNDSHK, DIO_DIR_OUT);
   errNum += DIG_Prt_Config(DIO_BD,  5, DIO_NO_HNDSHK, DIO_DIR_OUT);

   errNum += DIG_Prt_Config(DIO_BD,  6, DIO_NO_HNDSHK, DIO_DIR_OUT);
   errNum += DIG_Prt_Config(DIO_BD,  7, DIO_NO_HNDSHK, DIO_DIR_OUT);
   errNum += DIG_Prt_Config(DIO_BD,  8, DIO_NO_HNDSHK, DIO_DIR_OUT);

   errNum += DIG_Prt_Config(DIO_BD,  9, DIO_NO_HNDSHK, DIO_DIR_IN );
   errNum += DIG_Prt_Config(DIO_BD, 10, DIO_NO_HNDSHK, DIO_DIR_IN );

   errNum += DIG_Prt_Config(DIO_BD, 11, DIO_NO_HNDSHK, DIO_DIR_OUT);

   if (errNum < 0) {
       Fmt( errStr, "%s", "DIO_Init ports" );
       return(-1);
   }
   
   return(0);
}


/*_______________________________________________
 *
 * Display the status of ADC port 0 in volts.
 */
int Display_ADC_Port_0()
{
    errNum += AI_VRead( AIO_BD, CHAN_0, GAIN_1, &valADC_0 );
    
    if (errNum < 0) {
	Fmt( errStr, "%s", "Display_ADC_Ports()" );
	return(-1);
    }
    
    return(0);
}


/*_ GET LOW/HIGH LIMITS ________________________________________________________
 *
 *  Function Get_Low_High_Limits reads specified low and high limits for each of
 *  the DC, Functional, and Parametric tests that Chinh Vu defined in his Memos
 *  "Re: IC Automatic Test Station" dated 8/18/92, "16 Channel Preamp Test
 *  Procedures" dated 9/10/92, and "16 Channel Shaper-amp Test Procedures" dated
 *  9/10/92.
 */

int Get_Low_High_Limits( double D[][3] )
{
    int fileLimits;  /* File handle for low/high limits returned by OpenFile */
    int numInDc;     /* Number of hex integer to read for DC tests           */
    int check;
    fileLimits = OpenFile( limitFileName, READ_ONLY, NO_TRUNC, ASCII );
    
    numInDc = 3*NUM_TESTS_DC;
    
    ScanFile( fileLimits, "%s>%*f[x]", numInDc, D );    /* Read DC Limit settings */
    
    check = ScanFile( fileLimits, "%s>%i%i", &max_Ctlk_Counts, &max_Bad_Ctlk_Cells ); /* Read Crosstalk limits */
    if( check != 2 ) {
        FmtOut ("Error reading crosstalk limits\n" );
        exit(1);
    }
    
    check = ScanFile( fileLimits, "%s>%i%i", &max_Sigma_Counts, &max_Bad_Sigma_Cells ); /* Read Noise limits */

    if( check != 2 ) {
        FmtOut ("Error reading noise limits\n" );
        exit(1);
    }
    
    check = ScanFile( fileLimits, "%s>%i%i", &max_Glitch_Counts, &max_Bad_Glitch_Cells ); /* Read Glitch limits */
    
    if( check != 2 ) {
        FmtOut ("Error reading glitch limits\n" );
        exit(1);
    }
    
    check =ScanFile( fileLimits, "%s>%i", &max_Linearity_Diff );  /* Read Linearity Limit setting */
    
    if( check != 1 ) {
        FmtOut ("Error reading linearity limit\n" );
        exit(1);
    }
    
    check =ScanFile( fileLimits, "%s>%i%i", &min_Gain, &max_Gain );  /* Read Gain Limit settings */
    
    if( check != 2 ) {
        FmtOut ("Error reading gain limits\n" );
        exit(1);
    }
    
    CloseFile( fileLimits );
    return(0);
}


/*_________________________________
 *
 * Read Parameters from a disk file.
 */
void ReadParameters( int parameterFile )
{
    int numSpec;  /* Number of format specifiers written */
    
    numSpec = ScanFile( parameterFile, "%s>%s", chipIDs      ); /* Read parameter */
    numSpec = ScanFile( parameterFile, "%s>%s", operatorName ); /* Read parameter */
    numSpec = ScanFile( parameterFile, "%s>%s", dataFileName ); /* Read parameter */
}


/*______________________________
 *
 * Ring computer bell "n" times.
 */
void RingBell( int n )
{
    int i;
    
    for ( i=0; i<n; i++ ) {
	FmtOut( "%c", 0x07 );   /* Ring bell */
	delay( 0.3 );
    }
}


/*_________________________________________
 *
 * Sets the Pre-amp's power supply voltage.
 */
int Set_PA_Volts( DACvolts )
     double DACvolts;
{
    dacVolts = DACvolts;
    errNum = AO_VWrite( AIO_BD, CHAN_0, DACvolts );
    
    if (errNum < 0) {
	Fmt( errStr, "%s", "Set_PA_Volts()" );
	return(-1);
    }
    
    return(0);
}


/*________________________________
 *
 * Compute the Standard Deviation.
 */
double Sigma( double data[], double mean )
{
    int i;
    double sumSq;  /* Sum of the squares of (data - mean) */
    
    sumSq = 0.0;
    
    for ( i=0; i<NUM_SAMPLES; i++ ) sumSq += (data[i]-mean) * (data[i]-mean);
    
    return( sqrt(sumSq/NUM_SAMPLES) );
}


/*______________________________
 *
 * Write Parameters to disk file.
 */
void WriteParameters( int parameterFile )
{
    int numSpec;  /* Number of format specifiers written */
    
    numSpec = FmtFile( parameterFile, "%s<%s\n", chipIDs          ); /* Write line */
    numSpec = FmtFile( parameterFile, "%s<%s\n", operatorName    ); /* Write line */
    numSpec = FmtFile( parameterFile, "%s<%s\n", dataFileName    ); /* Write line */
    numSpec = FmtFile( parameterFile, "%s<%s\n", datestr()       ); /* Write line */
    numSpec = FmtFile( parameterFile, "%s<%s\n", softwareVersion ); /* Write line */
}


Markus Oldenburg
Last modified: Fri Apr 16 14:59:13 CEST 1999