// HP35601A test program
// GPIB ADDR #15 (HP35601A)
// Dr. Simon Schroedle, Started: Jan 18, 2014
//

#include "ni4882.h"

#include <time.h>
#include <stdlib.h>
#include <stdio.h>


#define M_E 2.71828182845904523536
#define M_LOG2E 1.44269504088896340736
#define M_LOG10E 0.434294481903251827651
#define M_LN2 0.693147180559945309417
#define M_LN10 2.30258509299404568402
#define M_PI 3.14159265358979323846
#define M_PI_2 1.57079632679489661923
#define M_PI_4 0.785398163397448309616
#define M_1_PI 0.318309886183790671538
#define M_2_PI 0.636619772367581343076
#define M_1_SQRTPI 0.564189583547756286948
#define M_2_SQRTPI 1.12837916709551257390
#define M_SQRT2 1.41421356237309504880
#define M_SQRT_2 0.707106781186547524401


int Device35601 = 0;                   /* Device unit descriptor                  */
int Device3585 = 0;                   /* Device unit descriptor                  */
int Device3562 = 0;                   /* Device unit descriptor                  */

int   PrimaryAddress3562 = 12;      /* Primary address of the device           */
int   SecondaryAddress3562 = 0;    /* Secondary address of the device         */

int   PrimaryAddress35601 = 15;      /* Primary address of the device           */
int   SecondaryAddress35601 = 0;    /* Secondary address of the device         */

int   PrimaryAddress3585 = 11;      /* Primary address of the device           */
int   SecondaryAddress3585 = 0;    /* Secondary address of the device         */

int BoardIndex = 0;               /* Interface Index (GPIB0=0,GPIB1=1,etc.)  */


void GpibError(const char * msg); /* Error function declaration              */


double tracedata[14][1020]; //final data to plot
double traceparameters[30]; //various parameters of trace
char tracetexts[10][40]; //various trace texts

char caltexts[10][40]; //various cal text
double calparameters[30]; //various parameters that are not cal constants
double Caldata[8][6]; //current cal data

int P82_C[11][1012]; //first 10 segments, 1 to 10 is used, segment 0 unused
int P85_C[14][1012]; //correction offsets calculated by Phioffs

int P82[11][1012]; //first 10 segments, 1 to 10 is used, segment 0 unused
int P85[14][1012];
//sements 11 to 13; -4 to 1000 index;
//original index "-3" P85[][1007] is valid data flag, 0:invalid; 1: valid
//original index "-2" P85[][1008] stopbin
//original index "-1" P85[][1009] startbin
//original index "0" P85[][1010] Hzpbin (/250, *10)


//3562a has 801 bins!
int P[14][3]={{0,0,0}, //entry seg 0   data are startbin stopbin and fmax
                 {0,0,0},   //entry seg 1
                 {0,0,0},   //entry seg 2
                 {4,800,4},  //seg 3 is lowest used for 3562a
                 {320,800,10}, //4
                 {200,800,40}, //5
                 {320,800,100}, //6
                 {200,800,400}, //7
                 {320,800,1000}, //8
                 {200,800,4000}, //9
                 {128,800,25000},   //10
                 {50,1000,50},   // 11 (SEGS 11-13 HAVE FMAX/10000)
                 {100,1000,500},    // 12
                 {125,1000,4000}   // 13
                };
//these are indices -2, -1, 0 to initialize P85 and P82
//new indices are 1008 1009 1010


double fac[]={1.0,10.0,100.0,1000.0,10000,100000,
              1000000,
              10000000,
              100000000,
              1000000000,
              10000000000,
              100000000000,
              1000000000000,
              10000000000000,
              100000000000000,
              1000000000000000};

double FROUND(double x, unsigned int digits) {  //round t a fixed number of decimals
    return round(x*fac[digits])/fac[digits];
}

double frand(void)
{
    return ((float)rand()/((float)(RAND_MAX)+1.0));
}

double FNPround(double Xi,double Round)
{
    double X,Det,Y;
    X=Xi;

    if (Round>0)
    {
       X=trunc(X);
       Det=fmod(X,pow(10,Round));
       X=trunc(X / pow(10,Round));
       X=X*pow(10,Round);
       if (Det>=(5*pow(10,(Round-1)))) { X=X+(1*pow(10,Round));}
    }
    if (Round==0)
    {
       Det=fmod(X,1);
       X=trunc(X);
       if ((Det*10)>=5) { X=X+1;}
    }
    if (Round<0)
    {
       Y=fmod(X,1);
       X=trunc(X);
       Y=Y/pow(10,Round);
       Det=fmod(Y,1);
       Y=trunc(Y);
       if (Det>=0.5) {Y=Y+1;}
       X=X+(Y*pow(10,Round));
    }
   return X;
}


double FNMax(double a1, double a2) //return max value of set of values
{
    double t;
    t=a1;
    if (a2>t) {t=a2;}
    return t;
}

double FNMax3(double a1, double a2, double a3) //return max value of set of values
{
    double t;
    t=a1;
    if (a2>t) {t=a2;}
    if (a3>t) {t=a3;}
    return t;
}


double FNMin(double a0, double a1) //return min value of set of values
{
    double t;
    t=a0;
    if (a1<t) {t=a1;}
    return t;
}



double fsgn(double t) //return sign of double number
{
    if (t<0) {return -1.0;}
    if (t>0) {return 1.0;}
    if (t==0) {return 0.0;}
}


double DROUND(double num, int n) { //round to a fixed number of significant digits
    double d,magnitude;
    int power;
    long shifted;


    if(num == 0) {
        return 0;
    }

    d = ceil(log10(num < 0 ? -num: num));
    power = n - (int) d;

    magnitude = pow(10, power);
    shifted = round(num*magnitude);
    return shifted/magnitude;
}


char latchd[20]={0,0x80,1,0x80,2,0x80,3,0x80,4,0x80,5,0x80,6,0x80,7,0x80,8,0x80,9,0x80};
//latch data latchd[0]=latch 0 latchd[1]=bit latch 0 usw., 0x80 set indicates bit data, 0x80 clear latch select

void zerolatch(void)//preset 35601 latches
{
    int i;
    for (i=1;i<20;i=i+2)
    {
        latchd[i]=0x80;
    }
}


void writelatch(void)
{
      ibwrt(Device35601, latchd, 20); //write all latch data
   if (Ibsta() & ERR) {
      GpibError("ibwrt Error");
   }
}

void CError(const char *msg)   //error handler for 35601A unknown command
{
    printf("\n!! Command error: %s\n",msg);
    exit(1);
}

void PError(const char *msg)   //error handler for incorrect parameter
{
    printf("\n!! Parameter error: %s\n",msg);
    exit(1);
}

/*
 ! RELAY  LATCH  LATCH  0,1
18560   !          #     BIT
18570   !  K1      2      3    INPUT TO FILTERS, AMP
18580   !  K2      1      6    CAL ON
18590   !  K3      1      2    TG TO CAL PATH
18600   !  K4      1      2    SAME AS K3
18610   !  K5      0      5    ARMSTRONG OFF, TG ON
18620   !  K6      0      3    TG TO PLL
18630   !  K7      0      7    TG ON
18640   !  K8      4      7    2MHZ LF FILTER
18650   !  K9      4      7    SAME AS K8
18660   !  K10     4      3    SIGNAL TO PLL CKTS
18670   !  K11     2      7    AMP IN
18680   !  K12     2      5    FILTERS, AMP TO OUTPUT
18690   !  K13     1      4    1.5 GHZ MIXER, 18 GHZ MIXER
18700   !  K14     2      7    SAME AS K11
18710   ! ------------------------
18720   ! SWITCH  LATCH  LATCH
18730   !           #     BIT
18740   !  S1       9      6   3582A NOISE SOURCE TO SUM
18750   !  S2       1      1   TRACKING GEN TO SUM AMP
18760   !  S3       0      4   PLL CLOSED
18770   !  S4       0      6   SEARCH ON
18780   !  S5       2      6   SUM (xfer fn) TO 3582A
18790   !  S6       2      2   VCO CONTROL TO 3582A
18800   !  S7       3      1   X100 AMP TO 3582A
18810   !  S8       3      3   3585A 50 OHM TO 3582A
18820   ! -----------------------
18830   ! SWITCH  86  94
18840   !
18850   !  F0     0   0    100KHZ FILTER, LF BOARD
18860   !  F1     0   1    1KHZ FILTER
18870   !  F2     1   1    10HZ FILTER
18880   ! -----------------------
18890   ! SWITCH  LATCH  LATCH
18900   !           #     BIT
18910   !  L0       9      3   3582 NOISE INTO CHAN A
18920   !  L1       8      5   HF BOARD INTO LF BOARD
18930   !  L2       8      7   AC COUPLING
18940   !  L3       7      5   AC/DC FROM HF BOARD INTO CHANNEL B
18950   !  L4       7      1   LF PM X5 INTO CHANNEL B
18960   !  L5       9      5   LF PM X20 INTO CHANNEL B (ACTIVE LOW)
18970   !  L6       7      4   LF AM X5 INTO CHANNEL B
18980   !  L7       9      1   LF AM X5 INTO CHANNEL B
18990   !  L8       7      2   LF AM X20 INTO CHANNEL A
19000   !  L9       7      6   HF LOCK/OVERLOAD MONITOR INTO CHAN A
19010   !  L10      7      3   LF AM X20 INTO X5
19020   !  L11      8      3   LF 0=BANDPASS FILTER, 1=X2.5 AMP
19030   !  L12      9      2   LF PM X20 TO PHASE LOCK CONTROL
19040   !  L13      8      4   LF 0=EXTERNAL 10 MHZ, 1=VCXO TO SYNTH
19050   !  L14      8      1   LF SYNTH CONTROL 0=370 KHZ, 1=350 KHZ
19060   !  L15      8      2   LF PHASE LOCK CTRL 0=ADAPT, 1=WIDEBND
19070   !  L16      7      7   LF 3582 NOISE INTO PM X20
19080   !  L17      6      7   ARMSTRONG AM MODULATED
19090   !  L18      6      6   ARMSTRONG PM MODULATED
19100   !  L19      0      1   10 MHZ TO ARMSTRONG MODULATOR
19110   !  L20      0      2   10 MHZ TO LF BOARD
19120   !  L21      3      2   LF PHASE LOCK CTRL, 0=ADAPT,1=N BAND
19130   ! -----------------------
*/

const char k_v[40]={0,0,2,3,1,6,1,2,1,2,0,5,0,3,0,7,4,7,4,7,4,3,2,7,2,5,1,4,2,7,0,9,0,9,0,9,0,9,0,9};
const char s_v[20]={0,9,9,6,1,1,0,4,0,6,2,6,2,2,3,1,3,3,0,9};
//const char f_v[20]={8,6,9,4,9,4,0,9,0,9,0,9,0,9,0,9,0,9,0,9};
const char l_v[44]={9,3,8,5,8,7,7,5,7,1,9,5,7,4,9,1,7,2,7,6,7,3,8,3,9,2,8,4,8,1,8,2,7,7,6,7,6,6,0,1,0,2,3,2};


/*
22050   ! DAC   LATCH  LATCH
22060   ! BITS    #     BIT
22070   !  0      5      1
22080   !  1      4      5
22090   !  2      4      6
22100   !  3      4      4
22110   !  4      5      3
22120   !  5      5      5
22130   !  6      5      4
22140   !  7      5      2
22150   ! POS DAC 3      7
22160   ! NEG DAC 4      2
22170   ! ----------------
22180   ! GAIN1
22190   ! BIT
22200   !  0      5      7  4 dB STEPS
22210   !  1      5      6
22220   !  2      6      2
22230   ! ----------------
22240   ! GAIN2
22250   ! BIT
22260   !  0      6      1  2 dB STEPS
22270   !  1      6      4
22280   !  2      6      3
22290   ! ----------------
22300   ! LEAD LAG
22310   ! BIT
22320   !  0      3      6
22330   !  1      6      5
22340   !  2      9      7
22350   ! ----------------
22360   ! ATTEN1
22370   ! BIT
22380   !  0      1      7  x.1 0 dB
22390   !  1      2      4  x.2 6 dB
22400   !  2      1      5  x.5 14 dB
22410   !  3      1      3  x1  20 dB
22420   ! ----------------
22430   ! ATTEN2
22440   ! BIT
22450   !  0      3      4  x.5 6 dB (1),x1 0 dB (0)
22460   ! ----------------
*/

const char dac_v[16]={5,1,4,5,4,6,4,4,5,3,5,5,5,4,5,2}; //bits 0 to 7
const char dacpos_v[2]={3,7};
const char dacneg_v[2]={4,2};

const char gain1_v[6]={5,7,5,6,6,2}; // 4 db steps,0 to 28 db (7*4db=28) ; bits 0 to 2, same for others
const char gain2_v[6]={6,1,6,4,6,3}; // 2 db steps, 6 to 20 db  (7*2db=14db, 14db+6db=20db)

const char leadlag_v[6]={3,6,6,5,9,7};

const char atten1_v[8]={1,7,2,4,1,5,1,3}; //.1, .2, .5, 1 ; 4 steps; 0/6/14/20 valid numbers (dB)
const char atten2_v[2]={3,4}; //set: .5, clear:1.;  2 steps; 0/6 valid numbers (dB)


#define NOCOMMAND 0 //writes latch, but no command.
#define OVERLOAD 1
#define OUTOFLOCK 2
#define TOGGLEACDC 3

const char delimiters[] = " ,;:"; //command delimiters; use "," as default

static char token_s[255]; //just in case if needed for some error handling
static char cp_s[255];

void setup_i(const char *commands)
{
   int  k_nr,tcnt,u_nr;
   char  tc,clearl;
   char *token;
   char *cp;

   cp=cp_s;
   token=token_s;
   strcpy(cp,commands);

//   printf("command length: %i\n",strlen(cp));

   token = strtok (cp, delimiters);
   tcnt=0; //count tokens
   do
   {
     tcnt++;
     //printf("%i >%s<\n",tcnt,token);
     tc=token[0];
     if (tc==45) { clearl=1; } else{ clearl=0;}
     tc=token[clearl];
     if (tc=='K') //handle relais
     { k_nr=atoi(token+1+clearl);
         if ((k_nr>0)&&(k_nr<15))
         {
             if (clearl)
             { latchd[(k_v[k_nr<<1]<<1)+1] &= ~(1<<(k_v[(k_nr<<1) + 1]-1));}
             else
             { latchd[(k_v[k_nr<<1]<<1)+1] |= 1<<(k_v[(k_nr<<1) + 1]-1); }
         }   else { CError(token); }
     } else
     if (tc=='S')
     { k_nr=atoi(token+1+clearl);
         if ((!clearl)&&((k_nr>=5)&&(k_nr<=8)))
         {
             for (u_nr=5;u_nr<=8;u_nr++)  //clear latches for 3582a input selector
                {latchd[(s_v[u_nr<<1]<<1)+1] &= ~(1<<(s_v[(u_nr<<1) + 1]-1));}
             printf("S5 to S8 cleared\n");
         }

         if ((k_nr>0)&&(k_nr<9))
         { if (clearl)
             { latchd[(s_v[k_nr<<1]<<1)+1] &= ~(1<<(s_v[(k_nr<<1) + 1]-1));}
             else
             {latchd[(s_v[k_nr<<1]<<1)+1] |= 1<<(s_v[(k_nr<<1) + 1]-1);}
         }   else { CError(token); }
     } else
     if (tc=='F')
     {
       k_nr=atoi(token+1);
         if ((k_nr>=0)&&(k_nr<3))
         {
           if (k_nr==0) //100 khz
           {
             latchd[(8<<1)+1] &= ~(1<<(6-1));  // latch 8 bit 6
             latchd[(9<<1)+1] &= ~(1<<(4-1));  // latch 9 bit 4
             printf("LPF set to 100 kHz.\n");
           }
           if (k_nr==1) //1 khz
           {
             latchd[(8<<1)+1] &= ~(1<<(6-1));
             latchd[(9<<1)+1] |= (1<<(4-1));
             printf("LPF set to 1 kHz.\n");
           }
           if (k_nr==2) //10 hz
           {
             latchd[(8<<1)+1] |= (1<<(6-1));
             latchd[(9<<1)+1] |= (1<<(4-1));
             printf("LPF set to 10 Hz.\n");
           }
         }   else { CError(token); }

     } else
     if (tc=='L')
     { k_nr=atoi(token+1+clearl);
         if ((k_nr>=0)&&(k_nr<22))
         { if (clearl)
             { latchd[(l_v[k_nr<<1]<<1)+1] &= ~(1<<(l_v[(k_nr<<1) + 1]-1));}
             else
             {latchd[(l_v[k_nr<<1]<<1)+1] |= 1<<(l_v[(k_nr<<1) + 1]-1);}
         }   else { CError(token); }
     } else {CError(token);}

     token = strtok (NULL, delimiters);
   } while (token!=NULL);

   writelatch();  //latch setzen
}

void toggle_i(int codei)
{
   switch (codei)
   {
     case NOCOMMAND:
         writelatch();
         break;
     case OVERLOAD:
        latchd[9] |= 0x01; //overload
        writelatch();
        latchd[9] &= ~(0x01);
        writelatch();
        //printf("overload reset OK\n");
        break;
     case OUTOFLOCK:
        latchd[7] |= 0x10; //out of lock
        writelatch();
        latchd[7] &= ~(0x10);
        writelatch();
        //printf("out of lock reset OK\n");
        break;
     case TOGGLEACDC:
        setup_i("-L2");
        setup_i("L2");
        wait_s01(5);
        break;

     default:
        CError("Invalid TOGGLE command.");
    }
}


#define NOVALUE     0x00 //updates latch from valued and sets latch
#define DAC         0x01
#define DACPOS      0x02
#define DACNEG      0x03
#define GAIN1       0x04
#define GAIN2       0x05
#define LEADLAG     0x06
#define ATTEN1      0x07
#define ATTEN2      0x08

char valued[9]={0,0,0,0,0,0,0,0,0}; //BIT data: empty, DAC, pos, neg, GAIN1, GAIN2, LEADLAG, ATTEN1, ATTEN2

void value_i(int codei,double valuei)
{
   int c_t;
   int i_t;
   double value_t;

   switch (codei)
   {
     case NOVALUE:
        break;
     case DAC:
        value_t=valuei/0.045; //convert 11.475 Volt to 8 bit, resolution about 0.045 V
        if (value_t>=0) {i_t=(int)value_t;valued[DACPOS]=1;valued[DACNEG]=0;}
          else {i_t=(int)(-1*value_t); valued[DACPOS]=0;valued[DACNEG]=1;}
        if ((i_t>=0)&&(i_t<256))
            { valued[DAC]=i_t;
              //printf("\n dac value: %i\n",i_t);
            } else {CError("Invalid DAC value");}

        break;
     case GAIN1: //0 to 28 db in 4 db steps
        i_t=(int) valuei;
        //printf("Gain1 %i",i_t);
        i_t=(i_t>>2)<<2; //make sure it is 4 db steps
        //printf("Gain1 v %i",i_t);

        if ((i_t>=0)&&(i_t<=28))
            { valued[GAIN1]=i_t;  //printf("\n GAIN1 value: %i\n",i_t);
            } else {CError("Invalid GAIN1 value");}

        break;
     case GAIN2: //6 to 20 in 2 db steps
        i_t=(int) valuei;
        i_t=(i_t>>1)<<1; //make sure it is 2 db steps

        if ((i_t>=6)&&(i_t<=20))
            { valued[GAIN2]=i_t;  //printf("\n GAIN2 value: %i\n",i_t);
            } else {CError("Invalid GAIN2 value");}

        break;
     case LEADLAG: //0 to 7
        i_t=(int) valuei;
        if ((i_t>=0)&&(i_t<=7))
            { valued[LEADLAG]=i_t;  //printf("\n LEADLAG value: %i\n",i_t);
            } else {CError("Invalid LEADLAG value");}

        break;
     case ATTEN1:
        i_t=(int) valuei;
        if ((i_t!=0)&&(i_t!=6)&&(i_t!=14)&&(i_t!=20)) {CError("Invalid ATTEN1 value");}
        valued[ATTEN1]=i_t;
        break;
     case ATTEN2:
        i_t=(int) valuei;
        if ((i_t!=0)&&(i_t!=6)) {CError("Invalid ATTEN2 value");}
        valued[ATTEN2]=i_t;
        break;
     default:
        CError("Invalid VALUE command.");
    }


    //set latch values based  on valuei data
    //DAC
    for (c_t=0;c_t<8;c_t++)
    {
      if ((valued[DAC]>>c_t)&0x01)
             {latchd[(dac_v[c_t<<1]<<1)+1] |= 1<<(dac_v[(c_t<<1) + 1]-1);
               //printf("value: %i, bit %i set\n",valued[DAC],c_t+1);
             }
             else
             {latchd[(dac_v[c_t<<1]<<1)+1] &= ~(1<<(dac_v[(c_t<<1) + 1]-1));}

    }
    if (valued[DACPOS]==0x01)
             { //printf("POSX %x\n",latchd[7]);
               latchd[(dacpos_v[0]<<1)+1] |= 1<<(dacpos_v[1]-1);
               //printf("POSY %x\n",latchd[7]);
               }
             else
             {latchd[(dacpos_v[0]<<1)+1] &= ~(1<<(dacpos_v[1]-1));}
    if (valued[DACNEG]==0x01)
             { //printf("NEGX %x\n",latchd[9]);
             latchd[(dacneg_v[0]<<1)+1] |= 1<<(dacneg_v[1]-1); //  printf("NEGY %x\n",latchd[9]);
             }
             else
             {latchd[(dacneg_v[0]<<1)+1] &= ~(1<<(dacneg_v[1]-1));}
    //GAIN1
    for (c_t=0;c_t<3;c_t++)
    {
      if ((valued[GAIN1]>>(c_t+2))&0x01)
             {latchd[(gain1_v[c_t<<1]<<1)+1] |= 1<<(gain1_v[(c_t<<1) + 1]-1);}
             else
             {latchd[(gain1_v[c_t<<1]<<1)+1] &= ~(1<<(gain1_v[(c_t<<1) + 1]-1));}
    }
   //GAIN2
    for (c_t=0;c_t<3;c_t++)
    {
      if (((valued[GAIN2]-6)>>(c_t+1))&0x01)
             {latchd[(gain2_v[c_t<<1]<<1)+1] |= 1<<(gain2_v[(c_t<<1) + 1]-1);}
             else
             {latchd[(gain2_v[c_t<<1]<<1)+1] &= ~(1<<(gain2_v[(c_t<<1) + 1]-1));}
    }
    //leadlag
    for (c_t=0;c_t<3;c_t++)
    {
      if ((valued[LEADLAG]>>c_t)&0x01)
             {latchd[(leadlag_v[c_t<<1]<<1)+1] |= 1<<(leadlag_v[(c_t<<1) + 1]-1);}
             else
             {latchd[(leadlag_v[c_t<<1]<<1)+1] &= ~(1<<(leadlag_v[(c_t<<1) + 1]-1));}
    }
    //ATTEN1
    if (valued[ATTEN1]==20) { latchd[(atten1_v[0]<<1)+1] |= 1<<(atten1_v[1]-1); }
             else {latchd[(atten1_v[0]<<1)+1] &= ~(1<<(atten1_v[1]-1));}
    if (valued[ATTEN1]==14) { latchd[(atten1_v[2]<<1)+1] |= 1<<(atten1_v[3]-1); }
             else {latchd[(atten1_v[2]<<1)+1] &= ~(1<<(atten1_v[3]-1));}
    if (valued[ATTEN1]==6) { latchd[(atten1_v[4]<<1)+1] |= 1<<(atten1_v[5]-1); }
             else {latchd[(atten1_v[4]<<1)+1] &= ~(1<<(atten1_v[5]-1));}
    if (valued[ATTEN1]==0) { latchd[(atten1_v[6]<<1)+1] |= 1<<(atten1_v[7]-1); }
             else {latchd[(atten1_v[6]<<1)+1] &= ~(1<<(atten1_v[7]-1));}


    //ATTEN2
    if (valued[ATTEN2]==6) { latchd[(atten2_v[0]<<1)+1] |= 1<<(atten2_v[1]-1); }
             else {latchd[(atten2_v[0]<<1)+1] &= ~(1<<(atten2_v[1]-1));}

    writelatch(); //write all latch data to hp35601a
}



void print_i_setup(void)
{
    double dacv;

    printf("\nHP35601A Setup:\n");

    dacv=valued[DAC]*0.045;
    printf("\nDAC   ");
    if (valued[DACNEG]==1) {dacv=-dacv; printf("NEG");} else {printf("POS");}
    printf(" %3i %.3f V  (NEG/POS 0..255, -11.475..+11.475 V)\n",valued[DAC],dacv);

    printf("GAIN1      %2i dB (0-28 dB)\n",valued[GAIN1]);
    printf("GAIN2      %2i dB (6-20 dB)\n",valued[GAIN2]);
    printf("LEADLAG     %i (0-7)\n",valued[LEADLAG]);
    printf("ATTEN1     %2i (0/6/14/20 dB)\n",valued[ATTEN1]);
    printf("ATTEN2      %i (0/6 dB)\n",valued[ATTEN2]);
    printf("\n");
}


void wait_s01(int s01) //wait 100 ms intervals
{
  clock_t ticks1, ticks2;

  ticks1=clock();
  ticks2=ticks1;
  while((ticks2/(CLOCKS_PER_SEC/10)-ticks1/(CLOCKS_PER_SEC/10))<s01)
    ticks2=clock();
}


//this version modified for 3562a fft analyzer!
void Getfreqparms(double Beginfreq,double Endfreq, int *Beginindex,int *Endindex)
{

  // printf("Getfreqparms: %f\n",Beginfreq) ;

   if (Endfreq<=4) {*Endindex=3;} //lowest index for 3562a
   if (Endfreq>4) {*Endindex=4;}
   if (Endfreq>10) {*Endindex=5;}
   if (Endfreq>40) {*Endindex=6;}
   if (Endfreq>100) {*Endindex=7;}
   if (Endfreq>400) {*Endindex=8;}
   if (Endfreq>1000) {*Endindex=9;}
   if (Endfreq>4000) {*Endindex=10;}

   if (Endfreq>25000) {*Endindex=11;} //3585a indices
   if (Endfreq>500000) {*Endindex=12;}
   if (Endfreq>5e6) {*Endindex=13;}

   if (Beginfreq<4) {*Beginindex=3;} //index 3 is lowest index for 3562a
   if (Beginfreq>=4) {*Beginindex=4;}
   if (Beginfreq>=10) {*Beginindex=5;}
   if (Beginfreq>=40) {*Beginindex=6;}
   if (Beginfreq>=100) {*Beginindex=7;}
   if (Beginfreq>=400) {*Beginindex=8;}
   if (Beginfreq>=1000) {*Beginindex=9;}
   if (Beginfreq>=4000) {*Beginindex=10;}

   if (Beginfreq>=25000) {*Beginindex=11;} //3585a indices
   if (Beginfreq>=500000) {*Beginindex=12;}
   if (Beginfreq>=5e6) {*Beginindex=13;}
}


int rangedbv;
int stat;

unsigned char  Buffer[10000];             /* Read buffer                             */

unsigned int Display3585[1002];




double Loopbw1,Loopbw2,Loopbw3,W1,W2,W3;
double Loopbw1_actual;
double Vcofreq,Spec;
int Vcoindex, Vcoport;
double Laglead;
double Zerofreq[]={9.95,40.1,115.9,306,784,1.985E3,5E3,12.58E3,31612,79421,199511,501164};
      //         !Actual Leadfreqs for each lag-lead
          //     ! Plus 4 EXTERNAL lag-leads
double Laglead2; //               !Effective Lag-lead if external lag-lead used

double     C8=3.3E-8;               //  ! .033 uf
double     R25=4.823E+5;          //    ! 482K ohm


/*
10984   ! *  NAME: Fnw
10990   ! *  FUNCTION: Compute the xfer function value at W
10996   ! *  INPUT:  W, W1, W2, W3, Bw1
11002   ! *  OUTPUT: Returns the xfer funtion value
*/

double FNW(double W,double W1,double W2,double W3,double Bw1)
{
double Ang; //                    !Phase angle of loop correction
double Fw; //                     !F(w) -- loop correction factor
double Pole;
double R;//                      !Magnitude of loop correction
double Ww;//                     !W  squared
double Ww1;//                    !W1 squared
double Ww2;//                    !W2 squared
double Ww3;//                    !W3 squared

    Ww=W*W;
    Ww1=W1*W1*4.0;
    Ww2=W2*W2;
    Ww3=W3*W3;
//    ! W0=1/2
    R=2*M_PI*Bw1/W*sqrt((1+Ww/Ww2)*(1+0.25/Ww)/(1+Ww/Ww3)/(1+Ww/Ww1));
    Pole=W/1.75E+6;
    if (Pole>(M_PI/2.0)) {Pole=M_PI/2.0;}

    Ang=-atan(W/W1)+atan(W/W2)-atan(W/W3)-M_PI/2.0-atan(0.5/W)-Pole;
    Fw=-10*log10(1+2*R*cos(Ang)+R*R);

    return Fw;
}



/*
11080   ! *  NAME: Difcorrection
11086   ! *  FUNCTION: Use a differential correction technique to determine
11089   ! *            the correct values of W1 and Bw1 used by Fnw
11095   ! *  INPUT:  X(*), Y(*), W1, W2, W3, Bw1
11101   ! *  OUTPUT: W1, Bw1, Maxpointerror
*/



double X[1050],Y[1050];
double W1,W2,W3;
double Maxpointerror;
double Slope;

void Difcorrection(int N)
{
    double Sumslope;   //            !Sum of squares of slope
    double Sumfreq;    //            !Sum of freq correction needed
    double  Corr;      //            !Freq correction term
    double  Delta;     //            !Percent change to calculate derivitive
    double  Error;     //            !Current error for one point
    double Errsum;     //            !Sum of all errors
    double  Fw;        //            !F(w) -- loop correction factor
    double  Fwhigh;    //            !F(High)
    double  Fwlow;     //            !F(Low)
    double  High;      //            !Higher point in search check
    int I;            //             !For-next loop counter
    //double  Loopbw3;  //             !Closed loop bandwidth
    int Loopcount;    //             !# of times correction loop is executed
    double  Low;      //             !Lower point in search check
// ! INTEGER N        //             !Number of data points to use in fit
    double  Oldersum; //             !Last Errsum value
    double  Peaking; //              !Amount of peaking in loop above predicted
    double  Span;   //               !Frequency range to search for peak
    double  W;      //               !Radial freq

//   ! Calculate initial guess for W1 by the amount of extra peaking needed
//11170    No_look=0 !SET TO 1 TO LOOK AT DEBUG

    printf("\nLoopbw1: %0.1f  W3: %0.1f  W2: %0.1f  \n", Loopbw1,W3,W2);
    Loopbw3=Loopbw1*W3/W2;
    Span=10.0*M_PI*Loopbw3;
    Low=0.318197*Span+M_PI*Loopbw3/2.0;
    High=0.61803*Span+M_PI*Loopbw3/2.0;
    Fwlow=FNW(Low,1.0E+7,W2,W3,Loopbw1);
    Fwhigh=FNW(High,1.0E+7,W2,W3,Loopbw1);

   // printf("Loopbw3: %0.1f  Span: %0.1f\n", Loopbw3,Span);

    for (Loopcount=1;Loopcount<=8;Loopcount++)
    {
       Span=Span*0.61803;
       if (Fwlow<Fwhigh)
       {
         Low=High;
         Fwlow=Fwhigh;
         High=Low+(0.61803-0.38197)*Span;
         Fwhigh=FNW(High,1.0E+7,W2,W3,Loopbw1);
       }
        else
       {
         High=Low;
         Fwhigh=Fwlow;
         Low=High-(0.61803-0.38197)*Span;
         Fwlow=FNW(Low,1.0E+7,W2,W3,Loopbw1);
       }
    }
   // printf("Fwlow: %e\n", Fwlow);
   // printf("Y[N]: %e\n", Y[N]);

    Peaking=Y[N]-Fwlow;

    W1=1.0E+7;
    if (Peaking>0) {W1=2*M_PI*Loopbw3*(-1.1+6.33/Peaking+0.195/(Peaking*Peaking));}
    W1=FNMax(W1,2*M_PI*Loopbw3);

    printf("EXTRA PEAKING=%0.1f\n",Peaking);                     // ! DEL
    printf("INITIAL W1=%0.1f\n",W1);                             // ! DEL
    //printf("W2=%0.1f  Loopbw1=%0.1f\n",W2,Loopbw1);                         // ! DEL

    Oldersum=0;
    Loopcount=0;

//11272 Loop:  !

    for (Loopcount=1;Loopcount<=10;Loopcount++)
    {
//     ! Compute correction for W1 -- user-pole-freq
       Errsum=0;
       Sumfreq=0;
       Sumslope=0;
       for (I=1;I<=N;I++)
       {
          W=X[I]*2.0*M_PI;
          Fw=FNW(W,W1,W2,W3,Loopbw1);
          Delta=0.015+0.01*frand();
          Slope=(FNW(W,W1+W1*Delta,W2,W3,Loopbw1)-Fw)/(W1*Delta);
          Error=Fw-Y[I];
          Errsum=Errsum+fabs(Error);
          Sumslope=Sumslope+Slope*Slope;
          Sumfreq=Sumfreq-Slope*Error;
       }

       if (Errsum<0.04) {Loopcount=999;} // ! Return if total error small

       if  (fabs(Oldersum-Errsum)<0.005) {Loopcount=999;}

    if (Loopcount<999)
    {
       Corr=Sumfreq/Sumslope;
       if (fabs(Corr)>W1) {Corr=fsgn(Corr)*W1/2.0;}
       W1=Corr+W1;

//     ! Compute correction for Loopbw1 -- open-loop-gain

       Maxpointerror=0;
       Errsum=0;
       Sumfreq=0;
       Sumslope=0;

       for (I=1;I<=N;I++)
       {
          W=X[I]*2*M_PI;
          Fw=FNW(W,W1,W2,W3,Loopbw1);
          Delta=0.015+0.01*frand();
          Slope=(FNW(W,W1,W2,W3,Loopbw1+Loopbw1*Delta)-Fw)/(Loopbw1*Delta);
          Error=Fw-Y[I];
          Maxpointerror=FNMax(Maxpointerror,fabs(Error));
          Errsum=Errsum+fabs(Error);
          Sumslope=Sumslope+Slope*Slope;
          Sumfreq=Sumfreq-Slope*Error;
        }
    }
       if (Errsum<0.04) {Loopcount=999;} // ! Return if total error small
    if (Loopcount<999)
    {
//     ! Only allow corrections that are less than 1/4 the current value
       Corr=Sumfreq/Sumslope;
       if (fabs(Corr)>(Loopbw1/4.0)) {Corr=Loopbw1/4.0*fsgn(Corr);}
       Loopbw1=Corr+Loopbw1;
       Oldersum=Errsum;
    }

    }//loopcount
//11422 Diffcorrret:      !

    printf("FINAL W1=%0.1f\n",W1);//                ! DEL
    printf("MAX ERROR IN DIFCORRECTION IS: %0.2e\n\n",Maxpointerror);  //  ! DEL

}


double W,W5;
/*
10783   ! *  FUNCTION: Given a frequency, and other inputs, calculate the
10786   ! *             correction factors needed.
10792   ! *  INPUT:  Amplifier, Vcoport, Mixerfreq, Caldata(*), W1, W2, W3,
10795   ! *          Loopbw1, Phaseslope, Vcoslope, F
10801   ! *  OUTPUT: Returns correction factor (Still needs Bandwidth and gain)
*/
double FNCalpoint(int Amplifier,int Vcoport,double Mixerfreq,double W1,double W2,double W3,double Loopbw1,double Phaseslope,double Vcoslope,double F)
{
    double Cal; //              !Total calibration for point
    int Calnum; //              !Index into Caldata(*) for coeffecients
    double C1,C2,C3,C4,C5; //   !Calibration coeffecients
    int I; //                   !Dummy variable in call to Getfreqparms
    int Index; //               !Measurement index where data point would have been taken


    Getfreqparms(F,F,&I,&Index);

    C1=0;
    C2=0;
    C3=0;
    C4=0;
    C5=0;
  if (!(Vcoport))
  {

    if (Mixerfreq<9.5E+7)
    {
        C1=Caldata[1][1];
        C2=Caldata[1][2];
        C3=Caldata[1][3];
        C4=Caldata[1][4];  // !NO C5 FOR FILTER
    }

    if (Amplifier!=0)
    {
         if (Index<=4)
         {
            C1=C1+Caldata[2][1]+Caldata[2][2]*40.0+Caldata[2][3]*1600.0+Caldata[2][4]*64000.0+Caldata[2][5]/40.0;

         }
            else
         {

            if (Index==13) {Calnum=5;}
            if (Index==12) {Calnum=4;}
            if (Index==11) {Calnum=4;}
            if (Index<=10) {Calnum=3;}
            if (Index<=6) {Calnum=2;}
            C1=C1+Caldata[Calnum][1];
            C2=C2+Caldata[Calnum][2];
            C3=C3+Caldata[Calnum][3];
            C4=C4+Caldata[Calnum][4];
            C5=C5+Caldata[Calnum][5];
         }
    }
    C1=C1+Caldata[7][1]+Caldata[6][1];
    if (Index>10)
    {
        C2=C2+Caldata[7][2]+Caldata[6][2];
        C3=C3+Caldata[7][3]+Caldata[6][3];
        C4=C4+Caldata[7][4]+Caldata[6][4];
        C5=C5+Caldata[7][5]+Caldata[6][5];
    }

  }

    Cal=C5/F+C1+F*(C2+F*(C3+F*C4));

    if (!((Phaseslope==0) & (Vcoslope==0)))
    {

       W5=2.0*M_PI*33500.0;
       W=2.0*M_PI*F;

//   ! IF PHASESLOPE=0 THEN THIS IS A DISCRIMINATOR MEASUREMENT
       if (Phaseslope==0)
       {
           Cal=Cal+20.0*log10(Vcoslope)-20.0*log10(F);
       }

       if (Vcoport & (Phaseslope!=0))
       {
           Cal=Cal+20.0*log10(Vcoslope)-20.0*log10(F)+10.0*log10((1+(W/W5)*(W/W5))*(1+(W/W2)*(W/W2))/(1+(W/W3)*(W/W3)));
       }

       if ((!Vcoport) & (Phaseslope!=0))
       {
           Cal=Cal-20.0*log10(Phaseslope)-FNW(W,W1,W2,W3,Loopbw1);
       }


       if (Index<=2) {Cal=Cal+10.0*log10(1+1/(W*W));}
//   ! NOTE: Cal still needs bandwidth and gain (if amp in) corrections
    }
    return Cal;
}

void w3585(char *buf)
{

   //printf("Command: >%s<\n",buf);
   //printf("Length: %i bytes\n",strlen(buf));
   ibwrt(Device3585, buf, strlen(buf)); //write all latch data


   if (Ibsta() & ERR) {
      GpibError("ibwrt Error");
   }
}

void w3585d(char *buf) //for debug only
{

    printf("Command: >%s<\n",buf);
    printf("Length: %i bytes\n",strlen(buf));
   ibwrt(Device3585, buf, strlen(buf)); //write all latch data


   if (Ibsta() & ERR) {
      GpibError("ibwrt Error");
   }
}

void r3585(int cnt)
{
   ibrd(Device3585, Buffer, cnt); //read

   if (Ibsta() & ERR) {
      GpibError("ibrd Error");
   }
}

void rd3585(void)
{
   unsigned char tbuf[2004];
   int i;

   ibrd(Device3585, tbuf, 2004); //read

   if (Ibsta() & ERR) {
      GpibError("ibrd Error");
   }
   for (i=0;i<=1002;i++)
   {
     Display3585[i]=(tbuf[2*i]<<8)+tbuf[2*i+1];
   }
}


void waitfor3585(void)
{
   char stat;
      do {
      w3585("D6T4");
      r3585(2);
      stat=Buffer[0];
      } while ((stat&0x80)==0x80); //wait until sweep complete
}



void autorange85(void)
{
    char tbuf[10];
    int checkcount;
    int rangenum;

    printf("3585A: autorange85\n");

    w3585("RLDV AL0 AL1 SV4 R01");
    do
    {
        wait_s01(1);

        w3585("D6T4");
        r3585(2);
        stat=Buffer[0];
      //  printf("D6 Status: 0x%02X\n",stat&0xff);
    } while ((stat&0x03)==0x03);
    rangenum=0;
    do
    {
       rangenum++;
       sprintf(tbuf,"R%02d",rangenum);
       w3585(tbuf);
       toggle_i(OUTOFLOCK);
       checkcount=0;
       do {
        w3585("D6T4");
        r3585(2);
        stat=Buffer[0];
        checkcount++;
       } while (((stat&0x01)==0x01)&&(checkcount<51));
    }  while ( (rangenum<12) && ((stat&0x01)==0x01));
    rangedbv=rangenum*5-43;

    printf("rangenum: %d\n",rangenum);
    printf("rangedbv: %d\n",rangedbv);
}


void w3562(char *buf)
{

   ibwrt(Device3562, buf, strlen(buf));


   if (Ibsta() & ERR) {
      GpibError("ibwrt Error");
   }
}


void w3562b(char *buf, int len)
{

   ibwrt(Device3562, buf, len);


   if (Ibsta() & ERR) {
      GpibError("ibwrt Error");
   }
}

void w3562d(char *buf) //for debug only
{

    printf("Command: >%s<\n",buf);
    printf("Length: %i bytes\n",strlen(buf));
   ibwrt(Device3562, buf, strlen(buf));


   if (Ibsta() & ERR) {
      GpibError("ibwrt Error");
   }
}

void r3562(int cnt)
{
   ibrd(Device3562, Buffer, cnt); //read

   if (Ibsta() & ERR) {
      GpibError("ibrd Error");
   }
}


unsigned char Display3562[20000];
double Display3562t[2100]; //0 to 800, 801 data points for spectrum, 0 to 2047, 2048 points for time
double Display3562p[80]; //parameters

double Display3562bn[10000]; //binary



void rd3562(int len)
{
   ibrd(Device3562, Display3562, len); //read

   if (Ibsta() & ERR) {
      GpibError("ibrd Error");
   }

}

void rd3562b(int len)
{
   ibrd(Device3562, Display3562bn, len); //read

   if (Ibsta() & ERR) {
      GpibError("ibrd Error");
   }

}
char istate3562[1000];//instrument state
int istate3562_set=0;


void i3562_savestate(void)
{
   int i;

   int datal;

   w3562("DSAN");
   r3562(4);
   //printf("%c %c\n",Buffer[0],Buffer[1]);
   datal=Buffer[2];
   datal=datal<<8;
   datal|=Buffer[3];
   istate3562[0]=Buffer[2];//length data
   istate3562[1]=Buffer[3];//length data
   printf("3562A: %i bytes state dump received\n",datal);
   r3562(datal);
   if (datal==768)
   {
        for (i=0;i<datal;i++)
        {
            //printf("%2x",Buffer[i]);
            istate3562[i+2]=Buffer[i];

        }
        istate3562_set=datal;

        printf("Save 3562A state OK.\n");
   }else
   {
        printf("!!Error: 3562A state dump has incorrect length!\n");
        istate3562_set=0;
   }
}

void i3562_recallstate(void)
{
   if (istate3562_set>0)
   {
        w3562("LSAN#A");
        w3562b(istate3562,istate3562_set+2);//dump 2 bytes length and 768 bytes state data
        printf("Recalled 3562A state OK.\n");

   } else
   {
       printf("!! Error: Cannot recall 3562A state - no state saved.\n");
   }
}

int rangelevel3562[11]={0,0,27,20,10,0,-10,-20,-30,-40,-50}; //values in dbvrms

char range_s3562[20];
int range_3562;


double i3562_irtodouble(int i) //convert 3562 internal float to double
{
   long int m_t;
   int e_t;
    double d1,d2,d3;

       m_t=(Display3562[i]<<16)|(Display3562[i+1]<<8)|(Display3562[i+2]);
       e_t=(signed char) Display3562[i+3];
       d1=(double)(m_t&0x7fffff);
       if ((m_t&0x800000)==0x800000)
       {
           d1=-(8388608.0-d1); //0x800000 hex 2 complements
       }

       d2=(double)e_t;
       d3=pow(2,e_t)*d1/pow(2,23);
       return d3;
}

void i3562_autorange(void)
{

   int i,j;
   unsigned long LocalIbsta;
   char SpollByte;

   ibclr(Device3562);                 /* Clear the device                        */


  //w3562("PRST;LNRS;PSP2;FLAT;FLT1;FLT2;MGDB;PSPC;AUTO0;CH2;");
  w3562("AVOF;");
  w3562("SRQE;ISM64;");
  w3562("FRS100kHz;");
  printf("3562 autorange... dBVrms = ");
  i=2; // 2 is highest range
  j=0;
  do
  {

    sprintf(range_s3562,"C2RG%iDBV;",rangelevel3562[i]);
    w3562(range_s3562); //set range

    w3562("STRT"); //start, otherwise it doesn't sense overrange

    wait_s01(30);

    LocalIbsta = ibrsp (Device3562, &SpollByte);
    if (LocalIbsta & ERR) {
            printf ("\n!!Error: ibrsp failed. No more callbacks.\n");
        }
    //printf("%x \n",(unsigned char)SpollByte);
    printf("%i ",rangelevel3562[i]);

    if ((SpollByte&0x8f)==0x0b)//status change
    {
        w3562("SOV2;");
        r3562(1);
        //printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]);
        if (Buffer[0]==0x32)
        {
            printf(" Overload!");
            j=200;
        }


    } else { wait_s01(10);} //spoll every 1 s
    i++;
  } while (!((i>=11)|(j==200))); //no more than 100 seconds
  if (i==11) { if (j!=200){j=200;i=12;}};//if overrange is not reached in 10th range, set to 10th.
  i=i-2;
  if (j!=200)
  {
      printf("\n!!Error: 3562A autorange not complete!\n");
      range_3562=0;
  } else
  {
      printf("\n3562 autorange complete. Range: %i, %i\n",i,rangelevel3562[i]);
      range_3562=i;
  }

}

void i3562_setrange_c2(int range_i)//ranges 2 to 10
{

  ibclr(Device3562);                 /* Clear the device                        */

  sprintf(range_s3562,"C2RG%iDBV;",rangelevel3562[range_i]);

  w3562(range_s3562); //set range
}


void i3562_pwrspec_init(void)  //init for pwr spectrum
{
   ibclr(Device3562);                 /* Clear the device                        */

 //  w3562("RST;SNGL;");
  // wait_s01(300);

   w3562("PRST;LNRS;PSP2;FLAT;FLT1;FLT2;MGDB;PSPC;AUTO0;CH2;STBL;PSUN;VTRM;VLTS;");
   w3562("YSCL-150,10DB;");
   wait_s01(50);

   w3562("NAVG1ENT;");//1 avg stable mean
   w3562("FRS1000Hz;C2RG3DBV;");
   w3562("SRQE;ISM4;");//enable SRQ and set end of meas mask
   w3562("STRT");//run to acquire some dummy data
   wait_s01(20);

}



void i3562_pwrspec(int segment_i,int range_i, int avg_i)  //acquire pwr spectrum
{
   unsigned long LocalIbsta;
   char SpollByte;

   time_t t;
   int i,j,c1,c2,k;
   char t_s[100];
   char tbuf[100];
   int datal,datal2;
   double d_t,d1,d2,d3;

   double maxrange,perdiv;

   long int m_t;
   int e_t;

   int timeout;


   ibclr(Device3562);                 /* Clear the device                        */


   sprintf(tbuf,"NAVG%iENT;FRS%iHz;",avg_i,P[segment_i][2]);
   w3562(tbuf);

   if (rangelevel3562[range_i]==100)
   {
      w3562("C2RG-10DBV;AU2U;");//AUTORANGE
   } else
   {
     sprintf(tbuf,"C2RG%iDBV;",rangelevel3562[range_i]);
     w3562(tbuf);
   }



   w3562("SRQE;ISM4;");//enable SRQ and set end of meas mask
   w3562("STRT");


   if (segment_i>6) {timeout=10;} else {timeout=100;} //1 s or 10 s timeout

   //getchar();
  i=0;
  do
  {
    LocalIbsta = ibrsp (Device3562, &SpollByte);
    if (LocalIbsta & ERR) {
            printf ("!!Error:ibrsp failed. No more callbacks.\n");

        }
    printf("%x ",(unsigned char)SpollByte);
      //w3562("IS?");
      //rd3562(2);
      //printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]);

    if ((SpollByte&0x8f)==0x0b)//status change
    {
        w3562("IS?;");
        r3562(2);
        printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]);
        //printf("%x %x\n",(unsigned char)Buffer[0]&0x04,(unsigned char)Buffer[1]);

     //   if ((Buffer[1]&0x04)==0x04)
     //   {

            i=200;
     //   } else {i=300;}//some other SRQ must have occured


    } else { wait_s01(timeout);} //spoll every 1 s or 10 s
     i++;
  } while (i<150); //no more than 150 //1500 seconds

  if (i!=201)
  {
      printf("!!Error: 3562A acquisition timeout! %i\n",i);
  } else {printf("3562A: Acquisition complete!\n");}

  ibclr(Device3562);                 /* Clear the device                        */

   w3562("DDBN");  //dump binary
   r3562(4);
   datal=Buffer[2];
   datal=datal<<8;
   datal|=Buffer[3];
 //  printf("3562A: %i bytes binary data dump received\n\n",datal);
   rd3562(datal);
   c1=0;
   for (i=168;i<datal;i=i+4)
   {
    /*   m_t=(Display3562[i]<<16)|(Display3562[i+1]<<8)|(Display3562[i+2]);
       e_t=(signed char) Display3562[i+3];
       d1=(double)(m_t&0x7fffff);
       d2=(double)e_t;
       d3=pow(2,e_t)*m_t/pow(2,23);
       //printf("%i, %i %i   %2x %2x %2x  %e\n",c1,m_t,e_t,Display3562[i],Display3562[i+1],Display3562[i+2],d3);*/
      // Display3562t[c1]=d3;
       Display3562t[c1]=i3562_irtodouble(i);
       c1++;
    }
    if (c1!=801)
    {
        printf("!!Error: Did not receive 801 points for trace! %i points received!\n",c1);
    } else
    {
        printf("Trace received OK. 801 points.\n");

    //    for (i=0;i<10;i++)
    //    {
    //        printf("%3i: %e ",i,Display3562t[i]);
    //        printf("%3i: %4.2f ",i,20.0*log10(Display3562t[i]));
    //    }

        perdiv=i3562_irtodouble((59<<1)-2);
        maxrange=i3562_irtodouble((61<<1)-2);
        printf("\n Hz per div: %0.2e, V maxrange: %0.2e, fullx Hz: %0.3f\n",perdiv,maxrange,perdiv*800.0);

        for (i=0;i<=800;i++)
        {
            P82[segment_i][i]=(int)(10.0*20.0*log10(Display3562t[i]));            //values in dbVrms (x10)
        }
        P82[segment_i][1007]=1; //valid trace
    }


}

int i3562_init_done;

void i3562_timeb_init()//setup for time measurement
{
   ibclr(Device3562);                 /* Clear the device                        */

   w3562("PRST;AVOF;AUTO0;CH2;REAL;FILT;TMR2;TLN200MSEC;C2RG-10DBV;");
}

int Display3562i[2100];
int i3562_timeb_valid;


void i3562_timeb(double tlength_s)  //acquire time buffer
{
   unsigned long LocalIbsta;
   char SpollByte;

   time_t t;
   int i,j,c1,c2,k;
   char t_s[100];
   int datal,datal2;
   double d_t;
   double maxrange,perdiv;
   double dsum;


   i3562_timeb_valid=0;

   ibclr(Device3562);                 /* Clear the device                        */

   //w3562("RST");

   sprintf(t_s,"AVOF;AUTO0;CH2;REAL;FILT;TMR2;TLN%0.3fSEC;C2RG-10DBV;",tlength_s);
   w3562(t_s);
   //w3562("FRS1000Hz;C2RG3DBV;");

   w3562("SRQE;ISM4;");//enable SRQ and set end of meas mask
   w3562("STRT");
  // wait_s01(40);
  // w3562("STRT");

   //w3562("STRT");



   //getchar();
  i=0;
  do
  {
    LocalIbsta = ibrsp (Device3562, &SpollByte);
    if (LocalIbsta & ERR) {
            printf ("!!Error:ibrsp failed. No more callbacks.\n");

        }
      printf(".");
    //printf("%x \n",(unsigned char)SpollByte);
      //w3562("IS?");
      //rd3562(2);
      //printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]);

    if ((SpollByte&0x8f)==0x0b)//status change
    {
        w3562("IS?;");
        r3562(2);
        //printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]);
        //printf("%x %x\n",(unsigned char)Buffer[0]&0x04,(unsigned char)Buffer[1]);

     //   if ((Buffer[1]&0x04)==0x04)
      //  {

            i=200;
      //  } else {i=300;}//some other SRQ must have occured


    } else { wait_s01(10+(int)tlength_s*10/10);} //spoll every x s
     i++;
  } while (i<100); //no more than 100 seconds

  if (i!=201)
  {
      printf("!!Error: 3562A acquisition timeout! %i\n",i);
  } else {//printf("3562A: Acquisition complete!\n");
  }

  ibclr(Device3562);                 /* Clear the device                        */


  //w3562("PRST;LNRS;PSP2;FLAT;FLT1;FLT2;MGDB;PSPC;AUTO0;CH2;");



 // getchar();



   w3562("DDBN");  //DDAN
   r3562(4);
   datal=(unsigned char)Buffer[2];
   datal=datal<<8;
   datal|=(unsigned char)Buffer[3];
   //printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]);
   //printf("%x %x\n",(unsigned char)Buffer[2],(unsigned char)Buffer[3]);
 //  printf("3562A: %i bytes binary data dump received\n\n",datal);
   rd3562(datal);

   perdiv=i3562_irtodouble((59<<1)-2);
   maxrange=i3562_irtodouble((61<<1)-2);
   //printf(" per div: %e, maxrange: %e, fullx: %f\n",perdiv,maxrange,perdiv*2048.0);

//   for (i=(53<<1);i<168;i=i+4)
//   {
//     printf("%i: %e\n",i/2,i3562_irtodouble(i-2));
//   }


   c1=0;
   for (i=168;i<datal;i=i+4)
   {

       //printf("%i, %i %i   %2x %2x %2x  %e\n",c1,m_t,e_t,Display3562[i],Display3562[i+1],Display3562[i+2],d3);
       Display3562t[c1]=i3562_irtodouble(i);
       c1++;
    }
    if (c1!=2048)
    {
        printf("!!Error: Did not receive 2048 points for trace! %i points received!\n",c1);
    } else
    {
       // printf("Trace received OK. 2048 points.\n");

     //   for (i=0;i<2047;i++)
     //   {
     //      if ((Display3562t[i]>0)&&(Display3562t[i+1]<0)) printf("-: %i ",i);
     //      if ((Display3562t[i]<0)&&(Display3562t[i+1]>0)) printf("+: %i ",i);
     //   }
        dsum=0.0;
        for (i=0;i<2047;i++)
        {
           dsum+=Display3562t[i];
        }
        dsum=dsum/2048.0;

        for (i=0;i<2047;i++)
        {
           Display3562i[i]=(int)( (Display3562t[i]-dsum)/maxrange*512.0); //scale to -512 to +512
        }
        i3562_timeb_valid=1;

    }


}



void i3562_charloop_init(int frange_i,int avg_i)
{
   char tbuf[100];
   ibclr(Device3562);                 /* Clear the device                        */

   w3562("PRST;LNRS;FRSP;FRQR;HANN;FLT1;FLT2;MGDB;AUTO0;CH12;");
   w3562("YSCL-40,40DB;");
   wait_s01(50);

   w3562("SRCE;RND;SRLV0.50VRMS;");
   wait_s01(5);

   sprintf(tbuf,"FRS%iHz;EXP;AVG%iENT;",frange_i,avg_i);
   w3562(tbuf);

   w3562("C2RG-10DBV;AU2U;C1RG-10DBV;AU1U;");//AUTORANGE
   w3562("SRQE;ISM4;");//enable SRQ and set end of meas mask
   w3562("STRT;");//run to acquire some dummy data
   wait_s01(20);

}


void i3562_charloop(int frange_i,int avg_i)
{
   unsigned long LocalIbsta;
   char SpollByte;

   time_t t;
   int i,j,c1,c2,k;
   char t_s[100];
   char tbuf[100];
   int datal,datal2;
   double d_t,d1,d2,d3;

   double maxrange,perdiv,yscalef;

   long int m_t;
   int e_t;

   int timeout;

   Display3562t[1000]=-1234.0;//to identify correct record later

    LocalIbsta = ibrsp (Device3562, &SpollByte);
    if (LocalIbsta & ERR) {
            printf ("!!Error:ibrsp failed. No more callbacks.\n");

        }
   wait_s01(10);
   ibclr(Device3562);                 // Clear the device

   sprintf(tbuf,"FRS%iHz;STBL;NAVG%iENT;",frange_i,avg_i);
   w3562(tbuf);


   w3562("C1RG-10DBV;AU1U;C2RG-10DBV;AU2U;");//AUTORANGE
   wait_s01(50);

   ibclr(Device3562);                 // Clear the device

   w3562("SRQE;ISM4;");//enable SRQ and set end of meas mask
   w3562("STRT;FRQR;");
   wait_s01(10);


   timeout=10+(int)(25.0*1.0/(double)frange_i);

   //getchar();
  i=0;
  do
  {
    LocalIbsta = ibrsp (Device3562, &SpollByte);
    if (LocalIbsta & ERR) {
            printf ("!!Error:ibrsp failed. No more callbacks.\n");

        }
    printf("%x ",(unsigned char)SpollByte);
      //w3562("IS?");
      //rd3562(2);
      //printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]);

    if ((SpollByte&0x8f)==0x0b)//status change
    {
        w3562("IS?;");
        r3562(2);
        printf("%x %x\n",(unsigned char)Buffer[0],(unsigned char)Buffer[1]);
        //printf("%x %x\n",(unsigned char)Buffer[0]&0x04,(unsigned char)Buffer[1]);

     //   if ((Buffer[1]&0x04)==0x04)
     //   {

            i=200;
     //   } else {i=300;}//some other SRQ must have occured


    } else { wait_s01(timeout);} //spoll every 1 s or 10 s
     i++;
  } while (i<150); //no more than 150 //1500 seconds

  if (i!=201)
  {
      printf("!!Error: 3562A acquisition timeout! %i\n",i);
  } else {printf("3562A: Acquisition complete!\n");}

   wait_s01(1);
   ibclr(Device3562);                 // Clear the device



   w3562d("DCBN");  //DDBN dump binary
   r3562(4);
   datal=Buffer[2];
   datal=datal<<8;
   datal|=Buffer[3];


   printf("3562A: %i bytes binary data dump received\n\n",datal);

   //datal=3500;
   rd3562(datal);


   ibclr(Device3562);                 /* Clear the device                        */

    //for (i=0;i<4000;i++)
    //{
    //  printf("%c",(unsigned char) Display3562[i]);
    //}

   c1=0;
   for (i=156+168;i<datal;i=i+4)
   {
     /*  m_t=(Display3562[i]<<16)|(Display3562[i+1]<<8)|(Display3562[i+2]);
       e_t=(signed char) Display3562[i+3];
       d1=(double)(m_t&0x7fffff);
       d2=(double)e_t;
       d3=pow(2,e_t)*m_t/pow(2,23);
       //printf("%i, %i %i   %2x %2x %2x  %e\n",c1,m_t,e_t,Display3562[i],Display3562[i+1],Display3562[i+2],d3);
       Display3562t[c1]=d3;*/
       Display3562t[c1]=i3562_irtodouble(i);
       c1++;
    }

     if (c1!=801)
    {
        printf("!!Error: Incorrect number of trace points received! %i points received!\n",c1);
    } else
    {
        printf("Trace received OK. \n");

    //    for (i=0;i<10;i++)
    //    {
    //        printf("%3i: %e ",i,Display3562t[i]);
    //        printf("%3i: %4.2f ",i,20.0*log10(Display3562t[i]));
    //    }

        perdiv=i3562_irtodouble(((59)<<1)-2+156);
        maxrange=i3562_irtodouble(((61)<<1)-2+156);
        yscalef=i3562_irtodouble((47<<1)+2);

        printf("\n %0.3f scale, Hz per div: %0.2e, V maxrange: %0.2e, fullx Hz: %0.3f\n",yscalef,perdiv,maxrange,perdiv*800.0);
        for (i=0;i<801;i++)
        {
            Display3562t[i]=Display3562t[i]*yscalef;
        //    printf("%i:%0.3f ",i,Display3562t[i]);
        }
        Display3562t[1001]=perdiv;//hzperdiv
        Display3562t[1000]=1234.0;//to identify correct record.

//        for (i=0;i<=800;i++)
 //       {
 //           P82[segment_i][i]=(int)(10.0*20.0*log10(Display3562t[i]));            //values in dbVrms (x10)
 //       }
 //
      //P82[segment_i][1007]=1; //valid trace
    }

}


double Approxfreq,Newfreq;


void i3562_frqcalc(double T_t)
{
   int Maxx;
   int Minn;
   int Startbin;
   int Startbinfound;
   int Endbinn;
   int Lastbin;

   int Crossingcount;
   int Binn;
   int Sign;
   int Numcycles;

   double Newfreq_t;
   double Endbin_d, Startbin_d;


   Maxx=300;
   Minn=-300;
   Crossingcount=0;
   Newfreq_t=-100.0;//no frequency found

   Sign=(Display3562i[0]>=0); //0 to 2047

   Startbin=0;
   Startbinfound=0;

   do
   {
       Startbin++;
       // printf("%i ",Display3562i[Startbin]);

       if (Sign!=(Display3562i[Startbin]>=0))
        {
            Startbinfound=Startbin;
         //   printf("Startbinfound %i\n",Startbin);
        }


   } while ((Startbin<2047)&&(Startbinfound==0));

   Startbin=Startbinfound;
    //printf("Startbin %i\n",Startbin);

   if (Startbinfound>0) //1st zero found
   {
        Crossingcount=1;
        Lastbin=Startbin;
        Sign=(Display3562i[Startbin]>=0);

        Startbin_d=(double)Startbin;
        if ((Display3562i[Startbin]-Display3562i[Startbin-1])!=0)
        {
           Startbin_d-=(double) Display3562i[Startbin]*1.0/(Display3562i[Startbin]-Display3562i[Startbin-1]);
        }


       // FIND POINT THAT IS HALF PEAK VALUE
      do{
        Binn=Lastbin;

         do {
            Binn++;
        } while (!((Binn>2047)||((Sign==1) && (Display3562i[Binn]>Maxx))||((Sign==0) && (Display3562i[Binn]<Minn))));

        if (Binn<2047)
        {
            //FIND ZERO CROSSING
            do
            {
                Binn++;
            }   while ((Binn<2047) && !(Sign!=(Display3562i[Binn]>=0)));

            if (Binn<2047)
            {
               Sign=(Display3562i[Binn]>=0);
               Crossingcount++;
               if (((Crossingcount-1)%2)==0) {Endbinn=Binn;}
               Lastbin=Binn;
            }
        }

      } while (Binn<2047);

     if (Crossingcount>=3)
     {
        Endbin_d=(double)Endbinn;

        if ((Display3562i[Endbinn]-Display3562i[Endbinn-1])!=0)
        {
            Endbin_d-=(double)Display3562i[Endbinn]*1.0/(Display3562i[Endbinn]-Display3562i[Endbinn-1]);
        }

        Numcycles=(Crossingcount-1) /2;
     //   printf("Crossings %i ",Crossingcount);

     //   printf("Start: %0.1f ",Startbin_d);
     //   printf("End: %0.1f: ",Endbin_d);

        Newfreq_t=1.0/( ((Endbin_d-Startbin_d))/((double)Numcycles)*T_t/2048.0);
     //   printf("Frequency found %0.6f\n",Newfreq_t);
        Newfreq=Newfreq_t;
     } else
     {
        printf("!! Error: Could not find sufficient zero crossings (%i found)!\n",Crossingcount);
     }

   }
    else
   {
       printf("!! Error: Could not find any zero crossing!\n"); //this error should not occur because of normalization/offset
   }

}


void getbeatnote(void)
{

int Binn;                //Binn number of beatnote
int Crossingcount;       //Number of zero crossings on 3582A display
int Endbinn;             //Binn # of last zero crossing
double Freq;                   //Freq of beatnote
int I;                   //For-next loop counter
int Lastbin;             //Bin number of latest zero crossing
int Maxx;                //Max of 3585A display, level needed
                               //  on 3582A time record to be valid
int Minn;                //Min level needed on 3582A time record
int Numcycles;           //Number of cycles on 3582A time record
int Order[4];               //The order in which freq spans are checked
int Rangenum;            //Freq range to be searched
int Sign;                //Sign of last 3582A display binn
int Startbin;            //Binn # of first zero crossing
int stat;                //Status of instrument
double T;                      //Number of seconds in time record
int frange; //currently tested range
char tbuf[30];

   //printf("getbeatnote... %0.1f Hz approx. ", Approxfreq);
   printf("getbeatnote... ");

   Newfreq=0;

   Order[1]=1;
   Order[2]=2;
   Order[3]=3;

   if ((Approxfreq<=85000) && (Approxfreq>100)) { Order[1]=2; Order[2]=1; Order[3]=3; }
   if (Approxfreq<=100) { Order[1]=3; Order[2]=2; Order[3]=1; }

    frange=1;
    do
    {
      Rangenum=Order[frange];

     if (Rangenum<3)
     {

      w3585("CN0 FA0HZ PR S2");
      if (Rangenum==1) { w3585("FB40MZ RB10KZ S2");}
      if (Rangenum==2) { w3585("FB85KZ RB300HZ S2");}

      do {
      w3585("D6T4");
      r3585(2);
      stat=Buffer[0];
      } while ((stat&0x80)==0x80); //wait until sweep complete

      w3585("C5CLSABOTB0");
      rd3585();
      Binn=2;
      Maxx=Display3585[2];
      for (I=3;I<=1000;I++)
      {
        if (Display3585[I]>=Maxx)
        {
          Binn=I;
          Maxx=Display3585[I];
        }
        //printf("%2u:%2X ",I,Display3585[I]&0xffff);
      }
      //printf("Maxx %u\n",Maxx);
      if (Maxx>=900) //sufficiently large signal found
      {

          sprintf(tbuf,"MK%dCN1 S3 RBUP D2 T6",Binn);
          //printf("%s\n",tbuf);
          w3585(tbuf);

          //printf("Read Frq...");
          wait_s01(5);
          r3585(12);
          Buffer[12]=0x00;
//          printf(">%s<\n",Buffer);

          Freq=atof(Buffer);

          w3585("TA0");
          if ((Binn>2)&&(Freq>=100.0)) {Newfreq=Freq;}
          //printf("%d\n",Binn);
          //printf("%f\n",Freq);
          //printf("New: %f\n",Newfreq);
      }

     } //end ranges 1 and 2 = 3585a ranges;
     // 3562a ranges for <=100 Hz

     if (Rangenum==3)
     {


        if (!i3562_init_done) {i3562_timeb_init();i3562_init_done=1;}

        if (Newfreq<=0)
        {
            i3562_timeb(0.4);
            i3562_frqcalc(0.4);
        }
        if (Newfreq<=0)
        {
            i3562_timeb(1.6);
            i3562_frqcalc(1.6);
        }
        if (Newfreq<=0)
        {
            i3562_timeb(16.0);
            i3562_frqcalc(16.0);
        }
        if (Newfreq<=0)
        {
            i3562_timeb(80.0);
            i3562_frqcalc(80.0);
        }
        if (Newfreq<=0)
        {
            i3562_timeb(320.0);
            i3562_frqcalc(320.0);
        }

     }

     frange++;
    } while ((frange<=3) && (Newfreq<0.01));


    if (Newfreq>4.01E+7) {Newfreq=0;}
    if (Newfreq<.015) {Newfreq=0;}

    if (Newfreq>0)
    {
       printf("beat frequency found [Hz]: %8.1f\n",Newfreq);
    }  else
    {
        printf("!!Error: Could not find beat frequency!\n");
    }

}




void Phi(int I,int Numelem,double *X,double *X1)
{
    int K;

//printf("call phi %d %d\n",I,Numelem);
    switch (I)
    {
    case 1: for (K=1;K<=Numelem;K++) {
        X1[K]=(1);
       }
     break;
    case 2: for (K=1;K<=Numelem;K++) {
        X1[K]=(X[K]);
       }
     break;
    case 3: for (K=1;K<=Numelem;K++) {
        X1[K]=(X[K]*X[K]);
       }
     break;
    case 4: for (K=1;K<=Numelem;K++) {
        X1[K]=(X[K]*X[K]*X[K]);
       }
     break;
    case 5: for (K=1;K<=Numelem;K++) {
        X1[K]=(1/X[K]);
       }
     break;
    }

}


double FNDot(int Numelem,double *E,double *F)
{
   int I;
   double Total;
//printf("call FNDot\n");
   Total=0;

   for (I=1;I<=Numelem;I++)
   {
      Total=Total+E[I]*F[I];
   }
   return Total;
}




void curvefit(double *X,double *Y,int Numelem,int N,double *C1,double *C2,double *C3,double *C4,double *C5) //Numelem: number of x, y elements; N number of coefficients
{
     int I,J,K;
     double C[5];
     double Element;
     double X1[100],X2[100],Temp[5][10],V[5],B[5][5];


//    ! Compute normal equations

//printf("Fit1\n");
     for (I=1;I<=N;I++)
     {
        Phi(I,Numelem,X,X1);
        for (J=1;J<=N;J++)
        {
           Phi(J,Numelem,X,X2);
           B[I][J]=FNDot(Numelem,X1,X2);
           B[J][I]=B[I][J];
        }
        V[I]=FNDot(Numelem,X1,Y);
     }
//    !MAT INVERSE GAUSS JORDAN REDUCTION
//printf("Fit2\n");
     for (I=1;I<=N;I++)
     {
        for (J=1;J<=N;J++)
        {
           Temp[I][J]=B[I][J];
           Temp[I][N+J]=0; //!INIT IDENTITY
         }
        Temp[I][I+N]=1;
     }
//    !DO DIAG
//printf("Fit3\n");
     for (I=1;I<=N;I++)
     {
        Element=Temp[I][I];

        for (K=1;K<=2*N;K++)
        {
           Temp[I][K]=Temp[I][K]/Element;
        }
//    !SET ELEMENTS OF COL=0
        for (K=1;K<=N;K++)
        {
           if ((K-I)!=0)
           {
             Element=Temp[K][I];
             for (J=1;J<=2*N;J++)
             {
                Temp[K][J]=Temp[K][J]-(Element*Temp[I][J]);
             }

           }
        }
     }
//printf("Fit4\n");
     for(I=1;I<=N;I++)
     {
        for (J=1;J<=N;J++)
        {
            B[I][J]=Temp[I][J+N];
        }
     }
//printf("Fit5\n");
//  !INVERSE FINISHED
     for (I=1;I<=N;I++)
     {
        C[I]=0;
        for (J=1; J<=N; J++)
        {
          C[I]=C[I]+B[I][J]*V[J];
        }
     }
//printf("Fit6\n");
     *C1=C[1];
     *C2=C[2];
     *C3=C[3];
     *C4=C[4];

     if (N==4)  { *C5=0; } else { *C5=C[5]; }

}




double Vrangemax; //             !Maximum allowable voltage tuning range
double Vrangemin; //              !Minimum allowable voltage tuning range

double Vrange;  //                 !voltage tuning range
double Vnom;   //   nominal tuning voltage

double Atten1; //                !Setting of attenuator 1
double Atten2; //                !Setting of attenuator 2
double Atten1db; //                !Setting of attenuator 1
double Atten2db; //                !Setting of attenuator 2


double Gain1;  //                !Setting of Gain1 (dB)
double Gain2; //                 !Setting of Gain2 (dB)

double Mixerfreq; //input frequency
double Userfrange; //frequency tuning range of user osc

double Vcoslope;
double Rin;

double Fbeatnote,Vbeatnote; //this is the setting used for the phase slope determination
//values are set by getvcoslope function

double Vnom_new; //suggested Vnom if zero beat too far off initial Vnom;
double Lockvoltage; //lock voltage

void getvcoslope(void)
{
    double B1,B2,B3,B4,B5;     //    !Coeffecients from least-squares fit
    double C1,C2,C3,C4,C5;    //     !Coeffecients from least-squares fit
    double Currentfreq;      //      !Present value of beatnote freq
    double Deltaf;          //       !Maximum freq change between beatnotes
    double Deltav;         //        !Control voltage step size
    double F0;             //        !Freq intercept (Freq at 0 volts)
    double Favg;          //         !Average of 4 freqs
    double F1linear;     //          !Linear approximation of Frequency(1)
    double F4linear;    //           !Linear approximation of Frequency(4)
    double Freq;       //            !Freq of user's oscillator
    double Maxfbeatnote; // max beatnote freq
    char tbuf[20];
    int Rangenum;
    int Trialcount;

    double Voltage[10],Voltagea[10],Voltagen[10];
    double Frequency[10],Frequencyn[10],Frequency2[10];

    double V,Vlower,Vupper,dacv,Vavg;

    double Lin, Lin2, Linslope;
    double Total;

    int i,j;

    int Maxindex;

    i3562_init_done=0;

    Vnom_new=Vnom;

    Deltav=Vrange*0.30;
    if ((Mixerfreq>=9.5E+7) && (Userfrange>5.0E+7)) { Deltav=Deltav*(5.0E+7/Userfrange);}
    if ((Mixerfreq<9.5E+7) && (Userfrange>=2.E+6)) { Deltav=Deltav*(2.E+6/Userfrange);}

    Deltav=0.045*Atten1*(Deltav / (0.045*Atten1));

    Deltav=FNMax(0.045*Atten1,Deltav);

    Deltaf=100000;
    Maxfbeatnote=200000;
    if (Mixerfreq>=9.5E+7) { Maxfbeatnote=4.E+6;}

    ibclr(Device3585);                 // Clear the 3585
    if (Ibsta() & ERR) {
      GpibError("ibclr Error");
    }

    Rangenum=(int)((rangedbv+13+4)/5+6);   //! +4 IS FOR ROUNDING
    sprintf(tbuf,"SV4R%02d",Rangenum);
    w3585(tbuf);

    toggle_i(OVERLOAD);

    Vcoslope=0.0;
    Trialcount=0;
    Freq=4.0E+7;

//     ! Step thru 4 voltages and get frequencies
     Vlower=Vnom-1.5*0.045*Atten1*((Deltav+0.5*0.045*Atten1)/(0.045*Atten1));
     Vupper=Vnom+1.5*Deltav;
    // printf("lower: %0.3f upper: %0.3f step: %0.3f \n",Vlower, Vupper, Deltav);
    for(V=Vlower;V<=Vupper;V=V+Deltav)
    {

        if (Vcoslope==0.0)
        {
          //  printf("Set dac: %0.3f\n",V/Atten1);
            value_i(DAC,V/Atten1);
       }

        if (Vcoslope==0.0)
       {
            Approxfreq=Freq+Deltaf;
            getbeatnote();
            Freq=Newfreq;
        }

        if (Vcoslope!=0.0)
        {
           Freq=fabs(Vcoslope*(V-Vnom));
        }

        //IF Abortflag=1 THEN Abortvcoslope

        if (Freq!=0)
        {
          Trialcount++;

          if (Trialcount==2) {Deltaf=Freq+Frequency[1];}

          Voltage[Trialcount]=V;
          Frequency[Trialcount]=Freq;

          dacv=valued[DAC]*0.045*Atten1;
          if (valued[DACNEG]==1) {dacv=-dacv; }
          Voltagea[Trialcount]=dacv; //actual DAC output voltage

          printf("Trial %d: Voltage: %0.3f actual Voltage: %0.3f Frq: %0.1f\n",Trialcount,V,dacv,Freq);
        }
     }//end of for loop

     if (Trialcount==4)
     {
        printf("Calculating VCO slope... ");

        Vavg=0;
        for (i=1;i<=4;i++)
        {
            Vavg+=Voltagea[i];
        }
        Vavg=Vavg/4; //average voltage
        for (i=1;i<=4;i++)
        {
            Voltagen[i]=Voltagea[i]-Vavg;
        }
        Favg=0;
        for (i=1;i<=4;i++)
        {
            Favg+=Frequency[i];
        }
        Favg=Favg/4; //average frequency

        for (i=1;i<=4;i++)
        {
            Frequencyn[i]=Frequency[i]-Favg;
        }

  //      printf("%0.3f avg v; %0.3f avg f\n",Vavg,Favg);

        Lin=99999;

        for (i=1;i<=4;i++)
        {
            Frequency2[i]=Frequency[i];
        //     printf("Frq #%d: %0.3f n=%0.3f\n",i,Frequency[i],Frequencyn[i]);
        }

        for (i=0;i<4;i++) //reverse sign starting from lowest frequency, check for lowest lin dev
        {
            if (i!=0)
            {
                Frequency[i]=-Frequency[i]; //succesively reverse sign
            }
            Linslope=(Frequency[2]-Frequency[3])/(Voltagen[2]-Voltagen[3]);
            if (Linslope!=0.0)
            {
              F0=Frequency[2]-Linslope*Voltagen[2];//  ! Get y-intercept  (b=y-mx)
              F1linear=Linslope*Voltagen[1]+F0;      //! Get predicted value for f1
              F4linear=Linslope*Voltagen[4]+F0;      //! Get predicted value for f4
              Favg=(Frequency[2]+Frequency[3])/2;

              if (!((Favg==F1linear) | (Favg==F4linear) | (Favg==Frequency[1]) | (Favg==Frequency[4])))
              {
                 Lin2=fabs(log10(fabs((Frequency[1]-Favg)/(F1linear-Favg))));
                 Lin2=Lin2+fabs(log10(fabs((Frequency[4]-Favg)/(F4linear-Favg))));
                 //printf("%0.3f\n",Lin2);
                 if (Lin2<=Lin)
                 {
                   Lin=Lin2;
                   for (j=1;j<=4;j++)
                   {
                      Frequency2[j]=Frequency[j];
                   }

                 }

              }

            }
        }


     for (i=1;i<=4;i++)
     {
   //     printf("#%d:  DAC Voltage: %8.3f    Frequency: %12.3f\n",i,Voltagea[i],Frequency2[i]);
     }

     printf("Fitting...\n");

     curvefit(Voltagen,Frequency2,4,4,&C1,&C2,&C3,&C4,&C5);

     for (i=1;i<=4;i++)
     {
        Frequency[i]=Frequency2[i];
     }

     //Mat1(Voltagen(*),"+",Vavg,1,4)     ! Restore original voltages
     //Voltagea has actual DAC voltages
     //Voltagen has voltagea - avg voltage

     if (Lin>.30)
     {
          printf("ERROR: Tuning curve is not linear! Lin parameter (0.3 max): %0.3f\n",Lin);
     }

//    ! Calculate Vcoslope at the tuning curve center voltage (Vnom)
     Vcoslope=(C2+2*C3*(Vnom-Vavg)+3*C4*(Vnom-Vavg)*(Vnom-Vavg))*Atten1;

     printf("VCO slope of current system (Hz vs. DAC Voltage): %0.4f Hz/V\n",Vcoslope);

//    ! Check to see if the total frequency tuning range is < .2 Hz
     if (Vrange*2*fabs(Vcoslope)/Atten1<0.2)
     {
          printf("ERROR: Tuning range less than 0.2 Hz!\n");
     }

     Rin=600.0; //VCO input impedance; 35601A has 50 ohm output impendace.


     printf("Expected VCO slope (Hz vs. VCO input voltage, 600 Ohm): %0.4f Hz/V\n",Vcoslope*((Rin+50)/Rin)/Atten1);


     Total=0; // calculate avg freq
     for (i=1;i<=4;i++)
     {
         Total=Total+Frequency[i];
     }
     Favg=Total/4;

     for (i=1;i<=4;i++)
     {
          Frequencyn[i]=Frequency[i]-Favg;
     }

     printf("Calculate lock point...\n");
     for (i=1;i<=4;i++)
     {
    //    printf("#%d:  DAC Voltage: %8.3f   avg. Frequency: %12.3f\n",i,Voltagea[i],Frequencyn[i]);
     }


     curvefit(Frequencyn,Voltagea,4,4,&B1,&B2,&B3,&B4,&B5);

//    ! Calculate the predicted Lock voltage and retune if it is
//    ! not within 15% of the total tuning range (Vnom +-.15*Vrange)

    // printf("Vavg: %f\n",Vavg);
    // printf("Favg: %f\n",Favg);

     Lockvoltage=B1+B2*(-Favg)+B3*(-Favg)*(-Favg)+B4*(-Favg)*(-Favg)*(-Favg);

     if ((Lockvoltage>(Vnom+0.15*Vrange)) | (Lockvoltage<(Vnom-.15*Vrange)) )
     {
         printf("!! Warning: predicted lock voltage is not within 15%% of the total\n");
         printf("            tuning range, Vnom+-0.15*Vrange!\n");

         Vnom_new=0.045*Atten1*((Lockvoltage+0.0225*Atten1*fsgn(Lockvoltage)) / (0.045*Atten1));

         printf("!! Suggested Vnom = %0.3f Volt\n\n",Vnom_new);
     }
     //Lockvoltage=0.1;

//    ! Calculate the Vcoslope at the predicted lock point
     Vcoslope=fabs((C2+2*C3*(Lockvoltage-Vavg)+3*C4*(Lockvoltage-Vavg)*(Lockvoltage-Vavg))*Atten1);

     printf("Lock point, %e DAC Volt, VCO SLOPE = %e Hz/Volt\n",DROUND(Lockvoltage,3),DROUND(Vcoslope/Atten1,4));


//    ! Find the maximum vco frequency < Maxfbeatnote (Fbeatnote) and it's
//    ! DAC voltage (Vbeatnote). This will be used to measure Phase Slope.
     Maxindex=1;

     if (fabs(Frequency[4])>fabs(Frequency[1])) {Maxindex=4;}

     Fbeatnote=Frequency[Maxindex];

     if (fabs(Fbeatnote)>Maxfbeatnote) {Fbeatnote=Maxfbeatnote*fsgn(Fbeatnote);}

     Vbeatnote=0.045*((B1+B2*(Fbeatnote-Favg)+B3*(Fbeatnote-Favg)*(Fbeatnote-Favg)+B4*(Fbeatnote-Favg)*(Fbeatnote-Favg)*(Fbeatnote-Favg)) / 0.045);
     Fbeatnote=fabs(FNPround(C1+C2*(Vbeatnote-Vavg)+C3*(Vbeatnote-Vavg)*(Vbeatnote-Vavg)+C4*(Vbeatnote-Vavg)*(Vbeatnote-Vavg)*(Vbeatnote-Vavg),-3));

     printf("Beat note at %e DAC Volt, Freq = %e Hz\n",DROUND(Vbeatnote,3),DROUND(Fbeatnote,4));


     }
     else
     {
         printf("VCO slope could not be determined. Check setup/select other voltage range.\n");
     }
}





int Mixer;
double Mindac;
double Stfq,Spfq;
double Vswing;
int Numsam;
double Maxfreq;

void getuserparms(void)//this checks parameters and set up oscillator related variables
{

   Vrange=1.8;//+- voltage range
   Vnom=0.1;//center voltage of tuning curve

   Mixer=1; //1: 5 MHz to 1.6 GHz; 2: 1.2 to 18 GHz; 3: External 0.02 to 40.1 MHz
   Mixerfreq=28.8e6;//phase detector frequency

   Userfrange=1.0e6; //user total freq tuning range

   if (Mixerfreq>=9.5E+7)  {Maxfreq=4.0E+7;}
   if (Mixerfreq<9.5E+7) {Maxfreq=1.E+6;}


   if ((Vnom>10.0)|(Vnom<-10.0))
   {
       PError("Vnom out of range, use -10 to 10 Volts");
   }

   Vrangemax=12-fabs(Vnom);
   if (fabs(Vnom)<=2) {Vrangemax=10.035;}
   Vrangemin=0.18;
   if (fabs(Vnom)>0.765) {Vrangemin=0.36;}
   if (fabs(Vnom)>1.395) {Vrangemin=0.99;}
   if (fabs(Vnom)>3.96) {Vrangemin=1.98;}
   Vrange=fabs(Vrange);

   if ((Vrange<Vrangemin)|(Vrange>Vrangemax))
   {
       PError("Tuning range error!");
   }

   if ((Vrange+fabs(Vnom))>12)
   {
       PError("Center voltage+tuning range must be in -12 to 12 Volt range!");
   }

   Vswing=fabs(Vrange)+fabs(Vnom);
   Atten1=0.1;
   Atten1db=20;
   if (Vswing>1.2) {Atten1=0.2;Atten1db=14;}
   if (Vswing>2.4) {Atten1=0.5;Atten1db=6;}
   if (Vswing>6) {Atten1=1.0;Atten1db=0;}
   Mindac=0.045*Atten1;

   Vnom=Mindac*(floor(FNPround(Vnom/Mindac,-10)));
   Vrange=Mindac*(floor(FNPround(Vrange/Mindac,-10)));
   Vswing=fabs(Vrange)+fabs(Vnom);

   Atten1=0.1;
   Atten1db=20;
   if (Vswing>1.2) {Atten1=0.2;Atten1db=14;}
   if (Vswing>2.4) {Atten1=0.5;Atten1db=6;}
   if (Vswing>6) {Atten1=1.0;Atten1db=0;}
   Mindac=0.045*Atten1;


   Vnom=Mindac*(floor(FNPround(Vnom/Mindac,-10)));
   Vrange=Mindac*(floor(FNPround(Vrange/Mindac,-10)));

   printf("Center voltage of tuning curve: %0.3f Volt\n",Vnom);
   printf("Voltage tuning range: +- %0.3f Volt\n",Vrange);


   Atten2=1;
   Atten2db=0;
   if (Vrange<=(5*Atten1)) {Atten2=0.5; Atten2db=6.0;}

   if (Userfrange>1.0e6)
   {
       printf("Total frequency tuning range (user defined): %0.3f\n",Userfrange);
   }

   if (Userfrange<=1.0e6)
   {
       printf("Total frequency tuning range (user defined): less than or equal 1 MHz!\n");
   }

   switch (Mixer)
   {
       case 1: printf("Internal 5 MHz to 1.6 GHz mixer used.\n");
          if ((Mixerfreq<4.9e6)|(Mixerfreq>1600e6))
          {
              PError("Frequency must be in 4.9 MHz to 1600 MHz range. Check frequency or select other mixer!");
          }
       break;
       case 2: printf("Internal 1.2 to 18 GHz mixer used.\n");
          if ((Mixerfreq<1200e6)|(Mixerfreq>18000e6))
          {
              PError("Frequency must be in 4.9 MHz to 1600 MHz range. Check frequency or select other mixer!");
          }
       break;
       case 3: printf("External mixer. Connect mixer IF port to 35601A SIGNAL INPUT port.\n");

       break;
       default: PError("No mixer selected!");
       break;
   }
   printf("Phase detector input frequency: %0.1f Hz\n",Mixerfreq);

   Stfq=25000;//start freq
   Spfq=1e6;//stop freq
   Stfq=DROUND(Stfq,5);
   Spfq=DROUND(Spfq,5);

   if (Spfq<=Stfq) {printf("!!Error: Stop frequeny must be greater than start frequency!\n");}

   Numsam=1;//number of averages

   if ((Numsam<1)|(Numsam>999)) {printf("!!Error: Number of sample must be in range of 1 to 999!\n");}

}



int Amplifier=1; //K11 amplifier in or out
int AutoK11=1; //K11 amplifier out if overload
int Oldfilter=-1;
int Startindex,Stopindex;

void getdata(void) //perform actual data taking for a phase noise measurement
{
    int Rangenum;
    int Reflevel85;
    int Start85;
    int Stop85;
    int Index85;
    char tbuf[100];
    int SRQstate;
    char SerialPollResponse ;
    int Spectrum[1050];
    int I;

    for(I=11;I<=13;I++)
    {
        P85[I][1007]=0;//this is the data valid flag
        P85[I][1008]=P[I][0];
        P85[I][1009]=P[I][1];
        P85[I][1010]=P[I][2];
    }
    for(I=1;I<=10;I++)
    {
        P82[I][1007]=0;//this is the data valid flag
        P82[I][1008]=P[I][0];
        P82[I][1009]=P[I][1];
        P82[I][1010]=P[I][2];
    }


    if (Maxfreq<=1e6) {P85[12][1009]=200;} //limit 3585a to 2 MHz if 2 MHz filter is in.


  //**  if (Amplifier==1) {setup_i("K11");} else {setup_i("-K11");}
  //**  setup_i("K10,K12,S8,L1,L2,L3"); //set up for measurement

    wait_s01(20);

    toggle_i(OUTOFLOCK);


    autorange85();


    if (rangedbv>=-3)
    {
        printf("!!Warning: High noise power! Consider removing amplifer to avoid compression!\n");

       if (AutoK11==1)
       {
          setup_i("-K11,S8");
          printf("Note AutoK11: K11 amp has been removed to avoid compression!\n");
          Amplifier=0;
          autorange85();
       }
    }

    Rangenum=(rangedbv+13)/5+6;
    Reflevel85=rangedbv;
    Rangenum=FNMax(1,Rangenum-2);  // ! Down range by 10 dB

    ibclr(Device3585);                 // Clear the 3585
    if (Ibsta() & ERR) {
      GpibError("ibclr Error");
    }

    wait_s01(3);
    sprintf(tbuf,"AL0SV4R12RL%dDVR%02d",Reflevel85,Rangenum);
    w3585(tbuf); //setup 3585a

    //**missing: check if locked

    Getfreqparms(Stfq,Spfq,&Startindex,&Stopindex);

       //Sweepflag=0;


//    ! Get start and stop indexes for 3582A and 3585A

//    Start82=0
    Start85=0;
 //   Stop82=0
    Stop85=0;
 //   IF Startindex<=10 THEN Start82=Startindex
 // IF Startindex<=10 THEN Stop82=FNMin(10,(Stopindex))

     if (Startindex<11) {printf("!!Error: Freq index too low; not yet supported! Start index set to 11!\n");}
     if (Stopindex>=11) {Start85=FNMax(11,(Startindex));}
     if (Stopindex>=11) {Stop85=Stopindex;}

     Index85=Stop85;

//    ! Set up 3585A to take measurement
     w3585("PRRLDVAR0FA0HZMK1001S2D2");


     if (Index85==13) {w3585("C1 FB40MZ RB30KZ VB100HZ ST20SC RC4SV4");}
     if (Index85==12) {w3585("C1 FB5MZ RB10KZ VB30HZ ST20SC RC4SV4");}
     if (Index85==11) {w3585("C1 FB500KZ RB1KZ VB10HZ ST50SC RC4SV4");}
     w3585("T5");

//3517 Segment85loop:    ! loop here until sweep done (SRQ)
//3520  Phioff(P85(*),Index85,Vcoindex,Measuretype,Amplifier,Mixerfreq,Caldata(*),W1,W2,W3,Loopbw1,Phaseslope,Vcoslope,Vcofreq)
//3529 Seg85waitloop:   !


//    sprintf(tbuf,"SV4R%02d",Rangenum);
//    w3585(tbuf);

    printf("3585A start index: %d\n",Start85);
    printf("3585A stop index: %d\n",Stop85);
do {//index85 loop
     printf("waiting for 3585A data at index %d...\n",Index85);
     do {
      TestSRQ(BoardIndex,&SRQstate);
      //printf("%d",SRQstate&0x01);
      wait_s01(5);
    }
    while (!(SRQstate&0x01));

    TestSRQ(BoardIndex,&SRQstate);
   //printf("%d",SRQstate&0x01);
   //printf ( "Device asserted SRQ.1\n" );
    ibrsp ( Device3585, &SerialPollResponse);
    //TestSRQ(BoardIndex,&SRQstate);
    //printf("%d",SRQstate&0x01);
    //printf ( "SRQ cleared.2\n" );

    w3585("C5 CL SA TB0 BO");

    rd3585();//read data into Display3585 variable

    for (I=0;I<=1000;I++)
    {
        Spectrum[I]=(Display3585[I+1]);//first point is always 0xffff
        //if (I<15) {printf("%d: %u\n",I,Spectrum[I]);}
    }
    Spectrum[1000]=Spectrum[1000]&(int)1023;
    for (I=0;I<=1005;I++)
    {
        Spectrum[I]=10*(Reflevel85-100)+Spectrum[I];
        //if (I<5) {printf("%d: %d\n",I,Spectrum[I]);}
    }

//    !  SPECTRUM now contains raw spectrum data *10

    for (I=0;I<=1000;I++)
    {
        P85[Index85][I]=Spectrum[I];
  //      tracedata[Index85][I]=((double)Spectrum[I])/10.0;
    }
    P85[Index85][1007]=1; //valid trace
//    tracedata[Index85][1007]=1.0; //valid trace

     Index85=Index85-1;

 //**missing: check if still locked

     if (Index85==13) {w3585("C1 FB40MZ RB30KZ VB100HZ ST20SC RC4SV4");}
     if (Index85==12) {w3585("C1 FB5MZ RB10KZ VB30HZ ST20SC RC4SV4");}
     if (Index85==11) {w3585("C1 FB500KZ RB1KZ VB10HZ ST50SC RC4SV4");}

     w3585("D2T5"); //start next sweep

    } while (Index85>=Start85);

}

/*
11884   ! * NAME: Phaseslope
11887   ! *
11890   ! * FUNCTION: Measure the phase slope of the beatnote from the mixer.
11893   ! *
11896   ! * INPUT: Voltage, Atten1, Freq, Mixerfreq, Caldata(*), Rangedbv, Amplifier
11899   ! * OUTPUT: Phaseslope, Vpeak
! If Measuretype=0 then this routine is used to measure Phase Slope.
11986   ! The formula used to calculate phase slope is:
11989   !
11992   !  2^.5 * (V0 - 3*V1 + 5*V2 - 7*V3 + 9*V4 ...)
11995   !  V0-Vx are rms values of each harmonic component
11998   !
12001   ! Cutoffamp designates minimum levels that each
12004   ! harmonic must be greater than to be of significance.
12007   !
12010   ! Phaseslope can be in error if there is a significant amount of
12013   ! dc offset from the mixer.  This is taken into account by the
12016   ! term COS( ASN( Mixerdc/V0 )).
12019   !
12022   ! If Measuretype#0 then this routine is used to measure the amplitude of the
12025   ! input signal. No harmonics are needed so Fmax is set to
12028   ! twice the expected frequency.
*/

double Cutoffamp[19]={0.0,-100.0,0.0,
                      -49.5,0.0,-54.0,
                      0.0,-57.0,0.0,
                      -59.0,0.0,-61.0,
                      0.0,-62.3,0.0,
                      -63.5,0.0,-64.7,0.0};
                        //      !Amplitude rel to peak where harmonic becomes insignificant

double Phaseslope;
double Mixerdc;
double Vpeak;

void Getphaseslope(double Voltage,double Freq, int Measuretype,int Caltype)
{
    int Binc;             //   !For-next loop counter
    int Binn;              //  !Approximate display bin of response

    double Famp;             //      !Amplitude of particular freq
    double Famp1;           //       !Amplitude of fundamental
    double Fb;              //       !Maxfreq on 3585A span
    double Fmax;             //      !Max freq needed to measure phaseslope
    double Fullscale;        //      !Reflevel of 3582A
    int Harmonic;           // !Harmonic number being checked
    double Hzpbin;          //       !Hz per display bin
    int Maxbin;             // !Bin # of max response
    int Maxx;               // !Value of max response
    double Mixerdc1;        //       !Total dc in path
    double Mixerdc2;         //      !Residual dc in path
    int Numharmonics;       // !Number of harmonics to be checked
    int Rangenum;           // !Range number of 3585A
    int Sens;               // !Sensitivity setting of 3582A
    double Sign;               // !Sign of current harmonic value to be added
    int Span;               // !Span number of 3582A
    int Stat;               // !Result of STATUS read of instrument
    char tbuf[100];
    int I;
    int Display[1050];
    int Minbinnt;
    double FNCp;
    int SpanF; //max frequency of 3562

    printf("measuring phase slope...\n");


    Mixerdc=0;

    if (Measuretype==0)  { value_i(DAC,Voltage/Atten1);} //set beat note
    toggle_i(OVERLOAD);
    Fmax=Freq*10.0;
    if ((Measuretype==2) | (Measuretype==1) & (Caltype!=2))
    {
        Fmax=Freq*2.0;  // ! DISCRIMINATOR OR QUADRATURE CAL
    }

    if (Freq>=2500) //3585a used if >=2.5 khz
    {

    ibclr(Device3585);                 // Clear the 3585
    if (Ibsta() & ERR) {
      GpibError("ibclr Error");
    }
    wait_s01(3);

    Rangenum=(int)((rangedbv+13+4)/5+5);//  !+4 IS FOR ROUNDING
    Rangenum=FNMax(1,Rangenum);
    Rangenum=FNMin(12,Rangenum);
    Fb=1000.0*(Fmax / 1000.0+1.0); //     // !calculate max freq needed
    Fb=FNMin(4.01E+7,Fb);

    sprintf(tbuf,"R%02dFB%8.1fHZ PR RL UP UP RC4 SV4 S2S2",Rangenum,Fb);
    w3585(tbuf); //setup 3585a

     do {
      w3585("D6T4");
      r3585(2);
      stat=Buffer[0];
      } while ((stat&0x80)==0x80); //wait until sweep complete

      w3585("C5CLSA BO TB0");
      rd3585();

      for (I=0;I<=1001;I++)
      {
        Display[I]=Display3585[I];
      }

      Display[0]=Display[0]&1023;
      Display[1000]=Display[1000]&1023;

      Maxbin=0;//to avoid compiler warning
      Maxx=-200;
      Hzpbin=Fb/1000;
      Minbinnt=(int)(Freq/5.0/Hzpbin); //temporary variable for type conversion

      for (Binn=Minbinnt;Binn<=1000;Binn++)
      {
         if(Display[Binn]>Maxx) {Maxbin=Binn;}
         Maxx=FNMax(Display[Binn],Maxx);
      }

      Hzpbin=Fb/1000;
      Freq=Maxbin*Hzpbin;

      w3585("RLDVD7T4");
      r3585(100);
      //printf("\n%s\n",Buffer);
      for (I=3;I<10;I++) //extract ref level info
      {
          tbuf[I-3]=Buffer[I];
      }
      tbuf[6]=0;
      //printf("\n>%s<\n",tbuf);
      Fullscale=atof(tbuf);
      //printf("%f\n",Fullscale);

      Sign=1.0;
      Phaseslope=0;
      Numharmonics=9;
      if ((Measuretype==2) | (Measuretype==1) & (Caltype!=2))
      {
        Numharmonics=1;  // !IF Measuretype#0, NOT A BEATNOTE; this is for carrier ampl measurement
      }

      for (Harmonic=1; Harmonic<=Numharmonics; Harmonic=Harmonic+2)
      {
        Binn=(int)(Freq*Harmonic/Hzpbin);
        Maxx=-1;

        for (Binc=FNMax(10,Binn-25);Binc<=FNMin(1000,Binn+25);Binc++)
        {
          Maxx=FNMax(Maxx,Display[Binc]);
        }

        Famp=(double)Fullscale-(1000.0-(double)Maxx)/10;

        printf("found harmonic no. %d: amplitude: %0.2f\n",Harmonic,Famp);
        FNCp=FNCalpoint(Amplifier,0,Mixerfreq,0,0,0,0,0,0,Freq*Harmonic);
        Famp=Famp+FNCp;
        printf("%0.2f FNCalp, corrected amplitude: %0.2f\n",FNCp,Famp);


        if (Harmonic==1)  {Famp1=Famp;}



        if ((Famp-Famp1)>=Cutoffamp[Harmonic])
        {
          Phaseslope=Phaseslope+Sign*(double)Harmonic*pow(10,((double)Famp)/20);
          Sign=Sign*(-1.0);
        } else
        {
            printf("Harmonic no. %d below cut-off, %f!\n",Harmonic,Cutoffamp[Harmonic]);
            Harmonic=10000; //end loop
        }

      }

      if (Amplifier==1) {Phaseslope=Phaseslope/50;} // 40 db amp has 34 db=x50 amplification into 50 ohm because of series resistor!

      if ((Measuretype==2) & (Amplifier==1) & ((Caltype==2) | (Caltype==3))) {Famp1=Famp1-34;}
                    //with amp present, 40 db amp has 34 db gain into 50 ohm

      if (!((Measuretype==2) | (Measuretype==1) & (Caltype!=2)))
      {
/*
12541    OUTPUT I3582;"PRS HLT AA0 AB1 MD2 IM3 SC1 RP0 MN1 MP0 SP10 BS5 RUN"
12544    OUTPUT I3582;"AR"
12547    OUTPUT I3582;"AR"
12550    WAIT .7
12553    CALL Getdc(Mixerdc1)
12556    Setupinterface(" K2,-K12")
12559    OUTPUT I3582;"AR"
12562    WAIT .7
12565    Getdc(Mixerdc2)
12568    Setupinterface("-K2,K12")
12571    Mixerdc=Mixerdc1-Mixerdc2
*/
    //  }


     }

     }
        else  //use lf analyzer 3562a
     {

        SpanF=25000;
        if (Fmax<10000) {SpanF=10000;}
        if (Fmax<4000) {SpanF=4000;}
        if (Fmax<2000) {SpanF=2000;}
        if (Fmax<1000) {SpanF=1000;}
        if (Fmax<400) {SpanF=400;}
        if (Fmax<200) {SpanF=200;}
        if (Fmax<100) {SpanF=100;}
        if (Fmax<40) {SpanF=40;}
        if (Fmax<20) {SpanF=20;}
        if (Fmax<10) {SpanF=10;}
        if (Fmax<4) {SpanF=4;}
        if (Fmax<2) {SpanF=2;}
        if (Fmax<1) {SpanF=1;}

        Hzpbin=SpanF/800.0;

        i3562_pwrspec_init();

        rangelevel3562[0]=100;//autorange 3562

        P[0][2]=SpanF;

        i3562_pwrspec(0,0,1);


/*
        Sens=5-Rangedbv/10;
12193 Setupsens:  !
12196    Sens=FNMax(2,Sens-1)
12199    OUTPUT I3582;"HLT PRS AA0 AB0 MD2 IM3 BC2 RP0 AB1"
12202    OUTPUT I3582 USING "K,DD,K";"BS",Sens,"RUN"
12205    OUTPUT I3582 USING "K,DD,K";"SP",Span,"RE LST0"
12208    ENTER I3582 USING "#,B";Stat
12211    OUTPUT I3582;"AR"
12214   ! Load binary routine into 3582
12217    OUTPUT I3582 USING "12A,/,10(W)";"WTM,77200,10",46,12297,5,-3068,921,24617,13209,39,12297,-5680
12220   !
12223 Waitloop:  !
12226    OUTPUT I3582;"HLT,EXE,77200,RUN,LST1"   ! execute binary routine
12229    ENTER I3582 USING "#,B";Stat
12232    IF BIT(Stat,3) THEN Setupsens !IF OVERLOAD, BACK OFF SENSITIVITY
12235    IF NOT BIT(Stat,5) THEN Waitloop
12238   !
12241   ! Load display from 3582
12244    OUTPUT I3582;"HLTLFM,74400,256"
12247    ENTER I3582 USING "#,W";Display(*)
12250    OUTPUT I3582;"RUN"
*/
        Maxx=-2000;

        for (Binn=0;Binn<=(800-(int)(Freq/5.0/Hzpbin));Binn++)
        {
          // printf("%i ",P82[0][Binn]);
           if (P82[0][Binn]>Maxx) {Maxbin=Binn;}
           Maxx=FNMax(P82[0][Binn],Maxx);
        }
       // printf("found maxx: %i at %i",Maxx,Maxbin);

        Freq=Maxbin*Hzpbin;

        printf("Beat note found at %0.2f\n",Freq);

        Sign=1;
        Phaseslope=0;
        Numharmonics=9;

        if ((Measuretype==2) | (Measuretype==1) & (Caltype!=2)) {Numharmonics=1;}
                     //IF Measuretype#0, NOT A BEATNOTE

        for (Harmonic=1;Harmonic<=Numharmonics;Harmonic=Harmonic+2)
        {
            Binn=(int)(Freq*(double)Harmonic/Hzpbin);
            Maxx=-5000;
            // ! Find max display value of specific harmonic, searching +-5 bins
            // use +-15 bins because of 800 points for 3562a
            for (Binc=FNMax(2,Binn-15);Binc<=FNMin(799,Binn+15); Binc++)
            {
               Maxx=FNMax(Maxx,P82[0][Binc]);
              // printf("%i,%i\n",Binc,P82[0][Binc]);
            }
            Famp=FNPround((double)Maxx/10.0,-1); //in dBV

            printf("found harmonic no. %d: amplitude: %0.2f\n",Harmonic,Famp);
            FNCp=FNCalpoint(Amplifier,0,Mixerfreq,0,0,0,0,0,0,Freq*Harmonic);
            Famp=Famp+FNCp;
            printf("%0.2f FNCalp, corrected amplitude: %0.2f\n",FNCp,Famp);


            if (Harmonic==1)
            {
                Famp1=Famp;
            }


            if ((Famp-Famp1)>=Cutoffamp[Harmonic])
            {
                Phaseslope=Phaseslope+Sign*(double)Harmonic*pow(10,((double)Famp)/20);
                Sign=Sign*(-1.0);
            } else
            {
                printf("Harmonic no. %d below cut-off, %f!\n",Harmonic,Cutoffamp[Harmonic]);
                Harmonic=10000; //end loop
            }


        }

        if (Amplifier==1) {Phaseslope=Phaseslope/100;} // 40 db amp has x100 amplification into hi z

        if ((Measuretype==2) & (Amplifier==1) & ((Caltype==2) | (Caltype==3))) {Famp1=Famp1-40;}
                    //with amp present, 40 db amp has 40 db gain into hi z


           /*
         FOR Harmonic=1 TO Numharmonics STEP 2
12292       Binn=255-Freq*Harmonic/Hzpbin
12295       Maxx=-1
12298      ! Find max display value of specific harmonic, searching +-5 bins
12301       FOR Binc=FNMax(2,Binn-5) TO FNMin(254,Binn+5)
12304          Maxx=FNMax((Maxx),(Display(Binc)))
12307       NEXT Binc
12310       Famp=FNPround(Fullscale-(1023-Maxx)/(1023/80),-1)
12313       Famp=Famp+FNCalpoint(Amplifier,0,Mixerfreq,Caldata(*),0,0,0,0,0,0,Freq*Harmonic)

12316       IF Harmonic=1 THEN Famp1=Famp
12319       IF Famp-Famp1<Cutoffamp(Harmonic) THEN Gotphase82
12322       Phaseslope=Phaseslope+Sign*Harmonic*10^(Famp/20)
12325       Sign=Sign*(-1)
12328    NEXT Harmonic*/

    //   for (i=0;i<=800;i++)
    //    {
    //        P82[segment_i][i]=(int)(10.0*20.0*log10(Display3562t[i]));            //values in dbVrms (x10)
    //    }

/*
12253    Maxx=-200
12256    FOR Binn=1 TO 255-Freq/5/Hzpbin
12259       Display(Binn)=BINAND(Display(Binn),1023)
12262       IF Display(Binn)>Maxx THEN Maxbin=Binn
12265       Maxx=FNMax((Display(Binn)),(Maxx))
12268    NEXT Binn

12271    Freq=(255-Maxbin)*Hzpbin

12274    Fullscale=50-Sens*10
12277    Sign=1
12280    Phaseslope=0
12283    Numharmonics=9
12286    IF (Measuretype=2) OR (Measuretype=1) AND (Caltype<>2) THEN Numharmonics=1!IF Measuretype#0, NOT A BEATNOTE
12289
12331 Gotphase82:  !
12334    IF Amplifier=1 THEN Phaseslope=Phaseslope/100
12337    IF (Measuretype=2) AND (Amplifier=1) AND ((Caltype=2) OR (Caltype=3)) THEN Famp1=Famp1-40
12340    IF (Measuretype=2) OR (Measuretype=1) AND (Caltype<>2) THEN Phseslopecalc
12343    Display(255)=BINAND(Display(255),1023)
12346    Famp=FNPround(Fullscale-(1023-Display(255))/(1023/80),-1)
12349    OUTPUT I3582;"LFM,76000,1"
12352    ENTER I3582 USING "#,W";Sign
12355    Mixerdc1=10^(Famp/20)/2^.5
12358    Mixerdc1=Mixerdc1*SGN(Sign)
12361    Setupinterface(" K2,-K12")

12364    OUTPUT I3582;"HLT SC1 MN1 MP0 SP10 RUN"
12367    OUTPUT I3582;"AR"
12370    WAIT 1.3
12373    OUTPUT I3582;"LMK"
12376    ENTER I3582;Mixerdc2
12379    OUTPUT I3582;"LFM,76000,1"
12382    ENTER I3582 USING "#,W";Sign
12385    Setupinterface("-K2,K12")
12388    Mixerdc=FNPround(Mixerdc1-Mixerdc2*SGN(Sign)/2^.5,-6)
12391    DEALLOCATE Display(*)
12394    GOTO Phseslopecalc
    */

     }

//calculate phase slope from data

      Phaseslope=Phaseslope*pow(2.0,0.5);

      Vpeak=pow(10,(Famp1/20))*pow(2.0,0.5); // !peak value of fundamental, convert RMS to peak

      if (Measuretype==0)
      {

      //  PRINT "MIXERDC=";FNPround(Mixerdc,-4);"Volts   VPEAK=";FNPround(Vpeak,-4);"Volts"

    printf("Measured mixer DC = %e (dummy) Volt; Vpeak = %e Volt\n",FNPround(Mixerdc,-4),FNPround(Vpeak,-4));


    if (fabs(Mixerdc/Vpeak)>0.5)
        {printf("!! Error REF  314;DC OFFSET FROM MIXER > 1/2 PEAK VOLTAGE\n");}

    Phaseslope=Phaseslope*cos(asin(Mixerdc/Vpeak)); //correct for (small) DC component

    printf("Measured phase slope = %e Volt/Radian\n",FNPround(Phaseslope,-3));

    if ((Phaseslope<0.0195)|(Vpeak<0.0195))
        {printf("!! Error REF 312: PHASE SLOPE LESS THAN 20.0 mV\n");}

    if (Phaseslope>10.0)
        {printf("!! Error REF 313; PHASE SLOPE GREATER THAN 10 V\n");}

      }

}



void Lockcheck(int *Lockflag)
{

  //*** need to add!

  *Lockflag=1;
/*
10255   ! *
10258   ! *  NAME: Lockcheck
10261   ! *
10264   ! *  FUNCTION: Check to see if the PLL is locked.
10267   ! *
10270   ! *  INPUT:  Phaseslope
10273   ! *
10276   ! *  OUTPUT: Lockflag
10279   ! *
10282 Lockcheck:SUB Lockcheck(INTEGER Lockflag)
10285    COM /Loc_flags/ INTEGER C9835,I3582,I3585,I35601a,Clock,Plotter,Abortflag,Printer
10288    COM /Settings/ Latch(0:9)
10291    COM /Parm1/ REAL Cfq,Phaseslope,Vcoslope,I85amp,Loopbw1
10294    COM /Parm2/ REAL Vpeak,Vnom,Vrange,W1,W2,Mixerfreq,Errorspec,Mixerdc
10297    REAL Vswing
10300    REAL Gain
10303    REAL Gain1
10306    REAL Gain2
10309    REAL Dac         ! DAC VOLTAGE
10312    REAL Dc          ! Dc value from hf-board into 3582A
10315    REAL Atten1      ! Atten1 from hf_board
10318    REAL Atten2
10321    REAL Orgdac
10324    REAL Mixerdcg    !
10327    REAL I           ! For-next loop counter
10330    INTEGER Lockcount! Number of times lock has been checked
10333    INTEGER Loopcount! Loop counter
10336    INTEGER Maxx     ! Maximum of 3585A display
10339    INTEGER Rangenum ! Range setting for the 3585A
10342    ON KEY 19,5 GOTO Abortlockkey
10345    ALLOCATE Display(0:1001)
10348    ENABLE
10351    Lockflag=0
10354    Vswing=ABS(Vrange)+ABS(Vnom)
10357    Atten1=1/10
10360    IF Vswing>1.2 THEN Atten1=1/5
10363    IF Vswing>2.4 THEN Atten1=1/2
10366    IF Vswing>6 THEN Atten1=1
10369    Atten2=1
10372    IF Vrange<=5*Atten1 THEN Atten2=.5
10375    Gain=2*(20*LGT(Vrange/Atten1/Vpeak) DIV 2)
10378    IF Gain>54 THEN Gain=54
10381    Gain=Gain-12+6
10384    Gain=Gain+6*(Atten=.5)
10387    Gain2=20-Gain MOD 4
10390    IF Gain<18 THEN Gain2=Gain
10393    Gain2=FNMax(6,Gain2)
10396    Gain1=Gain-Gain2
10399    Mixerdcg=-1*(Atten2*Mixerdc*10^((Gain1+Gain2+6)/20))
10402    Dac=Vnom/Atten1
10405    Orgdac=Dac
10408   !
10411   ! CHECK FOR BEATNOTE IF NO BEATNOTE THEN CHECK FOR PLL
10414   !
10417    IF ABS(Mixerdcg)>.10*Phaseslope THEN Highbeat
10420    GOSUB Beatsearch
10423    IF Beatflag=0 THEN Checkflip!NO BEAT CHECK LOCK
10426   ! OPEN LOOP
10429    Setupinterface("-K10")
10432    WAIT 2.2
10435   ! CLOSE LOOP
10438    Setupinterface("K10")
10441    WAIT 1.2
10444    GOSUB Beatsearch
10447    IF Beatflag=1 THEN Lockcheckexit
10450 Checkflip: !
10453    Setupinterface("-L0,L9")
10456    DISP CHR$(130)&CHR$(127)&CHR$(128)&"CHECKING LOCK"
10459    OUTPUT I3582;"PRS,SC1,MN1,AC2,MP0"
10462    Loopcount=0
10465 Lockcheckloop:  !
10468    WAIT .5
10471    GOSUB Checklk    ! Check OUT OF LOCK FLIP on 3582A
10474    Loopcount=Loopcount+1
10477    IF (Loopcount<2) AND (Lockflag=0) THEN Lockcheckloop
10480    GOTO Lockcheckexit
10483 !
10486 ! POSSIBLE HIGHFREQ BEATNOTE NEED TO BRING IT IN
10489 !
10492 Highbeat:!
10495   ! FIND DAC STEP VOLTAGE
10498    IF (Dac-Mixerdcg<=0) AND (Dac>0) THEN Steps=-.2
10501    IF (Dac-Mixerdcg>0) AND (Dac>0) THEN Steps=-1
10504    IF Dac=0 THEN Steps=SGN(Mixerdcg)*.2*(-1)
10507    IF (Dac-Mixerdcg>=0) AND (Dac<0) THEN Steps=.2
10510    IF (Dac-Mixerdcg<0) AND (Dac<0) THEN Steps=1
10513    IF (SGN(Dac)<>SGN(Mixerdcg)) AND (SGN(Dac)<>0) THEN Steps=Steps*(-1)
10516    Finalv=Dac-Mixerdcg
10519    IF ABS(Finalv)>10.4 THEN Finalv=10.4*SGN(Finalv)
10522    GOSUB Movedac
10525    GOSUB Beatsearch
10528    Finalv=Orgdac
10531    Steps=Steps*(-1)
10534    IF Beatflag=0 THEN GOSUB Movedac
10537    IF Beatflag=0 THEN Checkflip
10540   !
10543   ! OPEN LOOP
10546   !
10549    Setupinterface("-K10")
10552    WAIT 2
10555    Setupinterface("K10")
10558    WAIT 1
10561    GOSUB Beatsearch
10564    GOSUB Movedac
10567    IF Beatflag=1 THEN Lockcheckexit
10570    GOTO Checkflip
10573 Abortlockkey: !
10576    DISP "MEASUREMENT ABORTED BY USER"
10579    BEEP
10582    WAIT 1
10585    Abortflag=1
10588    GOTO Lockcheckexit
10591 Abortlock1:   !
10594    DISP "REF 311; DAMAGING INPUT SIGNAL, MEASUREMENT ABORTED"
10597    Errorbeep
10600    WAIT 2
10603    Abortflag=1
10606    GOTO Lockcheckexit
10609 Lockcheckexit:!
10612    SUBEXIT
10615 !
10618 ! CHECK FOR PRESENCE OF BEATNOTE
10621 !
10624 Beatsearch:!
10627    CLEAR I3585
10630    Rangenum=(20*LGT(Phaseslope)+13)/5+6
10633    OUTPUT I3585 USING "K,ZZ,K";"R",Rangenum,"RC4 SV4 S2"
10636    Toggle("OUT OF LOCK")
10639    OUTPUT I3585;"S2"
10642 Sweepwait:OUTPUT I3585;"D6T4"
10645    ENTER I3585 USING "#,B";Stat
10648    IF BIT(Stat,7) THEN Sweepwait
10651    OUTPUT I3585;"C5CLSATB0BO"
10654    ENTER I3585 USING "#,W";Display(*)
10657    OUTPUT I3585;"S1"
10660    Display(0)=0
10663    Display(1)=0
10666    Display(1001)=0
10669    Total=0
10672    FOR I=0 TO 1001
10675       IF Display(I)>900 THEN
10678          Display(I)=1
10681       ELSE
10684          Display(I)=0
10687       END IF
10690       Total=Total+Display(I)
10693    NEXT I
10696    Beatflag=1
10699    IF Total=0 THEN Beatflag=0
10702    RETURN
10705 !
10708 ! MOVE DAC VOLTAGE
10711 !
10714 Movedac:!
10717    IF Mixerdcg=0 THEN RETURN
10720    FOR I=Dac TO Finalv-Steps STEP Steps
10723       Dac=Dac+Steps
10726       Setupbits("DAC",Dac)
10729    NEXT I
10732    Setupbits("DAC",Finalv)
10735    Dac=Finalv
10738    RETURN
10741   !
10744   !
10747   !
10750 Checklk:      !
10753    Lockflag=0
10756    Toggle("OUT OF LOCK")
10759    WAIT .5
10762    Getdc(Dc)
10765    IF Dc>2 THEN Abortlock1
10768    IF (Dc>=.9) AND (Dc<=2) THEN RETURN
10771    Lockflag=1     ! SET LOOP LOCKED FLAG
10774    RETURN   ! **FF****
10777 SUBEND
10780   ! *

*/
}



void Lagleadcalc(void)
{
    W2=2.0*M_PI*Zerofreq[(int)Laglead];
    W3=1.0/(R25*C8+1.0/W2);
    Loopbw3=Loopbw1*W3/W2;

//   ! Check to see if open loop bw is less than lag-lead pole freq W3
    if (Loopbw1<W3/(2.0*M_PI)) {Loopbw3=Loopbw1;}

//   ! Check to see if open loop bw is >= than pole-freq W3 and less than
//   ! lag-lead zero freq W2
    if ((Loopbw1>=W3/(2.0*M_PI)) & (Loopbw1<W2/(2*M_PI)))
        {Loopbw3=sqrt((Loopbw1*W3/(2.0*M_PI)));}

    printf("LAG LEAD=%0.1f\n",Laglead);
    printf("LOOP BANDWIDTH=%0.1f\n",Loopbw3);

    if (Laglead==0) {setup_i("-S4");} //search osc
    if (Laglead!=0) {setup_i("S4");}
    value_i(LEADLAG,Laglead);

    if (Loopbw3>20.0) {setup_i("-L0,L9,-S1,-S5,K7,K6,S2");} //connect tracking gen?
    if (Loopbw3<=20.0) {setup_i("L0,-L9,S1,S5,-K7,-K6,-S2");} //connect noise source?

    if ((Loopbw3>250000) & (Laglead!=7))
      {
          printf("!! Error: Loop bandwidth error REF 323; UNABLE TO ACHIEVE PHASE LOCK!\n");
      }
        else { printf("BW OK: LOOP BANDWIDTH=%0.2f Hz\n",FNPround(Loopbw3,-2));}

     Vcofreq=Loopbw3/4.0;
}


int Count; //               !Index counter
int Maxindex; //            !Index where max response occured
double Maxx; //                   !Value of max response


void i3562_get8db(void)   //this is part of charloop, returns count, X, Y; maxindex
{
    int i,j;
    int i_8db;
    double hzpbin,farout;
    double Rc2pi;





    if (Display3562t[1000]!=1234.0)
    {
        printf("!!Error: 3562A LOOP CHARACTERIZATION TRACE IS NOT VALID!\n");
    }

    farout=(Display3562t[800]+Display3562t[799]+Display3562t[798]+Display3562t[797]+Display3562t[796]+Display3562t[795])/6.0;
   // printf("%0.3f db far out\n",farout);

    hzpbin=Display3562t[1001];

    for (i=0;i<=800;i++)       //  offset correction, and 80db=800 scaling
    {
       Display3562t[i]=(Display3562t[i]-farout)*10.0;
    }


    Rc2pi=1.0e+5*1.0e-5*2.0*M_PI;

    for (i=0;i<=800;i++)       //  !CORRECTION FOR (1/(1+1/RCs))  AC COUPLER
    {
        Display3562t[i]=Display3562t[i]+10.0*10.0*log10(1+1/((Rc2pi*i*hzpbin)*(Rc2pi*i*hzpbin)));
    }


    Maxx=-20000;
    Maxindex=0;
//   ! FIND FIRST POINT < -8 dB

    i_8db=0;
    for (i=700;i>=2;i--)
    {
       if ((Display3562t[i]<-80.0)&(Display3562t[i-1]<-80.0)&(i_8db==0))
       {
           i_8db=i;
       }
       if (i_8db==0)
       {
           Maxx=FNMax(Display3562t[i],Maxx);
           if (Maxx==Display3562t[i]) {Maxindex=i;}
       }

    }

    Count=0;
    if (i_8db<10)
    {
      printf("!! Error: UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT! <-8 dB not found!\n");

    }
     else
    {

       printf("Maxindex: %i (%0.2f Hz);  8db: %i (%0.2f Hz)\n",Maxindex,Maxindex*hzpbin,i_8db,i_8db*hzpbin);
       for (j=i_8db;j<=FNMin(Maxindex+5,625);j++)
        {
            X[Count]=j*hzpbin;
            Y[Count]=Display3562t[j]/10.0;
            Count++;
        }
        Maxindex=Maxindex-i_8db+1;

        printf("Maxindex (offset to 8 dB): %i   Count: %i\n",Maxindex,Count);

    }
}



void Charloop() //int Pdv,int Vcoindex
{

    int Binn; //               !Bin # of display
    int Bwincrease; //         !0=ok to increase bandwidth, 1=already increased
    double C1,C2,C3,C4,C5; //        !Curve fit coeffecients
 //   double C8; //                     !Capacitor in lag-lead
    double Corner; //                 !Freq of pole in lag-lead

    double Fw; //                     !Value of transfer function at w
    double Gain; //                   !Amount of gain in programmable gains
  //  double Gain1; //                  !0->28 dB in 4 dB steps
  //  double Gain2; //                  !6->20 dB in 2 dB steps
    double Hzpbin; //                 !Hz per display bin
    double Hzpbin2; //                !Hz per bin used for plot of loop
    int I; //                   !For-next loop counter
    int J; //                   !For-next loop counter
    double Junk; //                   !Dummy variable for non-usable value read from the 3585A
    int Lockflag; //            !0=loop not locked, 1=loop locked
    //double Loopbw2; //                !

    //double Maxpointerror; //          !Max error determined by Difcorrection

    int N; //                   !Number of points for differential correction
    int Numsamples; //          !Number of samples on 3582A XFER function
    double Oldloopbw1; //             !Initial calculation of Loopbw1
  //  double R25; //                    !Resistor in lag-lead
    double Rc2pi; //                  !Product of 2*PI*R*C
    int Sens; //                !Sensitivity setting of the 3582A
    int Span; //                !Span number of the 3582A
    int Stat; //                !Status read from the 3582A or 3585A
    double Wi; //                     !Radian freq
    //double X[101]; //               !Freq's to be used for curve fit
    double X1; //                     !Freq to be put in X(*)
    //double Y[101]; //               !Amp's to be used for curve fit
    double Zero; //                   !Desired Leadfreq in lag-lead
    int forcellg2;
    int retrychar; //retry characterization at other laglead
    int Display[1050];
    char tbuf[100];
    int I_8db;
    int SpanF;//3562a frequency span

//   ! Zero freqs are calculated from the resistor selected by
//   ! the following formula:   f=1/(2*PI*(R+100)*C8)
//   ! 100 is the switch resistance

 //    C8=3.3E-8;               //  ! .033 uf
 //    R25=4.823E+5          //    ! 482K ohm


    printf("\nCharacterizing the loop...\n");

    ibclr(Device3585);                 // Clear the 3585
    if (Ibsta() & ERR) {
      GpibError("ibclr Error");
    }
    wait_s01(3);


//   ! DETERMINE GAIN SETTINGS
     Gain=2.0*(20.0*log10(Vrange/Atten1/Vpeak) / 2.0);

     if (Gain>54.0) {Gain=54.0;}
     Loopbw1=fabs(Phaseslope*Vcoslope*pow(10,Gain/20.0)); // ! OPEN LOOP BW
 printf("LOOP BW1 (uncorrected)=%e\n",Loopbw1);
     Loopbw1=Loopbw1/pow(10,(FNCalpoint(0,0,Mixerfreq,0,0,0,0,0,0,10000.0)/20.0));   //   ! ADJUST PHASESLOPE TO MEASUREMENT POINT
 printf("LOOP BW1 (FNCalp corrected)=%e\n",Loopbw1);
    Gain=Gain-12.0+6.0;          //  !TAKE OUT x4(12dB) AMPLIFIER AND 6dB PAD
    if (Atten2==0.5) {Gain=Gain+6;} //  !ADD 6 dB IF ATTEN2=.5
    Gain2=20.0-fmod(floor(Gain),4.0);     //  !CHOOSE 20 OR 18 dB FOR GAIN2
    if (Gain<18) {Gain2=Gain;}   //   !USE LESS IF GAIN<18
    Gain2=floor(Gain2/2.0)*2.0;
    Gain2=FNMax(6,Gain2);          //  !GAIN2 HAS 6 dB MIN
    Gain1=Gain-Gain2;         // !PUT REMAINING GAIN IN GAIN1
    Gain1=floor(Gain1/4.0)*4.0;

    Loopbw1_actual=fabs(Phaseslope*Vcoslope*pow(10,(Gain1+Gain2)/20.0)); // ! OPEN LOOP BW


    value_i(GAIN1,Gain1);
    value_i(GAIN2,Gain2);

    value_i(DAC,Vnom/Atten1);
  //  value_i(DAC,Lockvoltage); //only for unstable osciallators that are not within 15% range

    setup_i("L2,K10,S3"); //close loop
    wait_s01(20);
    toggle_i(OUTOFLOCK);

    printf("GAIN=%0.2f\n",Gain);
    printf("GAIN1=%0.2f\n",Gain1);
    printf("GAIN2=%0.2f\n",Gain2);
    printf("VCOSLOPE=%e Hz/V\n",Vcoslope/Atten1);
    printf("PHASESLOPE=%e V/rad\n",Phaseslope);
    printf("VPEAK=%0.2f V\n",Vpeak);
    printf("LOOP BW1=%e\n",Loopbw1);
    printf("LOOP BW1 (with actual gain)=%e\n",Loopbw1_actual);

    //Loopbw1=Loopbw1_actual;
    //printf("Note: using LOOP BW1 calcuated based on actual gain!\n");
    printf("Note: using LOOP BW1 calcuated based on %0.2f dB Gain!\n",Gain);

// ! Calculate BW assuming far out zero
    Corner=1.0/(2.0*M_PI*R25*C8);
    Loopbw2=sqrt(Loopbw1*Corner);  // ! Geometric mean, approximate cross-over

    printf("CORNER=%e\n",Corner);
    printf("LOOP BW2=%e\n",Loopbw2);

//   ! DETERMINE WHICH ZERO TO USE
    Zero=Loopbw2/sqrt(2.0);

    Laglead=0.0;

    for (I=11;I>=0;I--)
    {
       if (Zerofreq[I]<Zero) {Laglead=I;}
    }
    printf("INITIAL LAG LEAD CHOICE=%0.1f\n",Laglead);
    printf("NEEDED ZERO FREQ=%0.2e\n",Zero);
    printf("ACTUAL ZERO FREQ=%0.2e\n",Zerofreq[(int)Laglead]);

    Laglead2=Laglead;
    Bwincrease=0;

    forcellg2=0; //flag to force ext laglead2
    if (Laglead>7) {
            printf("!! Error REF 320; EXTERNAL LAG-LEAD MUST BE USED!\n");
            Laglead2=2; //lead lag for 35601A hardware, 0 to 7
            Laglead=4;  // Effective lead lag,  leadlag2 to 11
            Bwincrease=1; //       ! DON'T ALLOW LAGLEAD TO BE CHANGED

            value_i(LEADLAG,Laglead2);// ! FORCE LAGLEAD2
    }

    Lagleadcalc();

    if (forcellg2)  {value_i(LEADLAG,Laglead2);} // ! FORCE LAGLEAD2
    retrychar=0;
  do {  //this is the loop for characterization

//15745   ! CHECK TO SEE IF LOOP IS LOCKED
      Lockcheck(&Lockflag);
      if (Lockflag!=1)
        {

// ! IF NOT LOCKED, TRY TO INCREASE LOOP BANDWIDTH
            if ((Bwincrease==1) | (Laglead==0))
            {
                printf("!! Error: No lock, and cannot increase loop bandwidth any further!\n");
            } else
            {
                Laglead=Laglead-1; // !INCREASE LOOP BANDWIDTH
                printf("RETRY WITH NEW LAG LEAD CHOICE=%0.1f\n",Laglead);
                Bwincrease=1;
                Lagleadcalc();
                Lockcheck(&Lockflag);
                if (Lockflag!=1)
                {
                    printf("!! Error: No lock, even with other lag lead!\n");
                }
            }
        }

//15799 Startcharloop:         !
/*
15802    IF No_look THEN Skipplot
15805    IF Pdv<>9836 THEN Skipplot
15808    GINIT
15811    GCLEAR
15814    PEN 1
15817    GRAPHICS ON
15820    Beginexp=INT(LGT(Loopbw3)-2)
15823   !
15826    VIEWPORT 0,100,10,100
15829    LORG 5
15832    CSIZE 3,.6
15835    MOVE 70,95
15838    LABEL USING "#,K";"THEORETICAL & ACTUAL 'LOOP SUPPRESSION' FACTORS"
15841   !
15844    VIEWPORT 0,100,20,90
15847    WINDOW Beginexp,Beginexp+4,-10,10
15850    LINE TYPE 4,.30
15853    GRID 1,1,Beginexp,0
15856    LINE TYPE 1
15859    FRAME
15862    PENUP
15865 Skipplot:      !
15868   !
*/

//   ! USE 3585A FOR LOOP BANDWIDTHS >20 HZ
   if (Loopbw3<=20)
   {
       //printf("!! Warning: loop characterization for Bandwidth <20 Hz not yet implemented!\n");

        setup_i("L0,-L9"); //noise to 3562A a input

       SpanF=25000;
       if (Loopbw3<3000) {SpanF=10000;}
       if (Loopbw3<1500) {SpanF=5000;}
       if (Loopbw3<750) {SpanF=2500;}
       if (Loopbw3<300) {SpanF=1000;}
       if (Loopbw3<150) {SpanF=500;}
       if (Loopbw3<75) {SpanF=250;}
       if (Loopbw3<30) {SpanF=100;}
       if (Loopbw3<15) {SpanF=50;}
       if (Loopbw3<7.5) {SpanF=25;}
       if (Loopbw3<3) {SpanF=10;}
       if (Loopbw3<0.5) {SpanF=1;}
       Hzpbin=(double)SpanF/800.0;

       Numsamples=15*Hzpbin;

       Numsamples=FNMin((Numsamples),30);
       Numsamples=FNMax((Numsamples),4);

        toggle_i(TOGGLEACDC);

        i3562_charloop_init(SpanF,Numsamples);
        toggle_i(OUTOFLOCK);
        printf("OBSERVE 3582 DISPLAY OF LOOP SUPRESSION CHARACTERISTIC.\n");
        printf("EXCESSIVE NOISE MAY CAUSE ACCURACY SPEC DEGRADATION\n");
        printf("CHECK LOOP SUPPRESSION ON 3582A, THEN PRESS ANY KEY\n");
        getchar();

        printf("WAITING FOR AVERAGING ON 3562A OF CLOSED LOOP RESPONSE... ");
        i3562_charloop(SpanF,Numsamples);
        printf("done.\n");
        setup_i("-S1,-L0,L9"); //noise to 3562A a input
        toggle_i(OUTOFLOCK);

        i3562_get8db();

        if(Count>0) //valid xfer function found?
        {
          if ((Bwincrease==1) | (Laglead==0))
          {
              printf("!! Error: No lock, and cannot increase loop bandwidth any further!\n");
          } else
          {
              Laglead=Laglead-1; // !INCREASE LOOP BANDWIDTH
              printf("RETRY WITH NEW LAG LEAD CHOICE=%0.1f\n",Laglead);
              Bwincrease=1;
              Lagleadcalc();
              retrychar++;
          }
        }


    } else
  //for Loopbw3>20
  {

//follows: 3585 characerization
    Hzpbin=(Loopbw3*4.0/10)*0.01; // ! Span=BW3*4. Hzpbin in Units of .01 Hz.

    ibclr(Device3585);                 // Clear the 3585
    if (Ibsta() & ERR) {
      GpibError("ibclr Error");
    }
    wait_s01(3);

    sprintf(tbuf,"FB%8.1fHZ,R10,I1,SV4,S2",1000*Hzpbin);
    w3585(tbuf); //setup 3585a

//optional, to inspect:
    w3585("SV1 S1"); //save in register 1, single sweep

   // EnableLocal( BoardIndex,  PrimaryAddress3585 );                 // Local
   // if (Ibsta() & ERR) {
   //   GpibError("EnableLocal Error");
   // }

    printf("\nOBSERVE 3585 DISPLAY OF LOOP SUPRESSION CHARACTERISTIC.\n");
    printf("EXCESSIVE NOISE MAY CAUSE ACCURACY SPEC DEGRADATION \n");

    printf("CHECK LOOP SUPPRESSION ON 3585A, THEN PRESS ANY KEY\n");

    getchar();

    ibclr(Device3585);                 // Clear the 3585
    if (Ibsta() & ERR) {
      GpibError("ibclr Error");
    }
    wait_s01(3);
    w3585("RC1"); //recall register 1
    wait_s01(10);
//end of optional section

        toggle_i(OUTOFLOCK);
        printf("\nMEASURING CLOSED LOOP RESPONSE...\n");
        wait_s01(10);

        w3585("S2"); // !Start the sweep
        waitfor3585();

        w3585("SAAB1");

        setup_i("-S3,-S4"); // ! Open loop for reference sweep

        w3585("S2"); // !Start the sweep
        waitfor3585();

        setup_i("-K7,-K6,-S2,S3,S4"); // !Close loop again

        w3585("C5CLSABO");
        rd3585();

        for (I=0;I<=1000;I++) //cut out first point which has no display data.
        {
          Display[I]=Display3585[I+1];
        }
        Display[1000]=Display[1000]&1023;
        Display[0]=Display[0]&1023;


        for (I=0;I<=1000;I++)
        {
             Display[I]=500-Display[I]; // !SCALE FROM -500 TO 500
        }

        if (Display[1000]<-10)
        {
            printf("!! Error REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT (<-1 dB at end of sweep)!\n");
            // !Check for < -1 dB far out
        }

        I=1001;
        do
        {
           I--;
        } while ((!(  (Display[I]<-80)&(Display[I-1]<-80)  )) | (I<2));

        printf("Found -8 dB at bin %d, %0.1f Hz\n",I,Hzpbin*I);

        if (I<2)
        {
          printf("!! Error REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT! <-8 dB not found!\n");
        }

        //  ! -8 dB point found, increase loop bandwidth if invalid
         if ((I>500) & (Bwincrease==0))
         {
             printf("Warning: -8 dB too far out. Trying to increase loop BW...\n");
             if (Laglead>0)
             {
                 Laglead=Laglead-1; // !INCREASE LOOP BANDWIDTH
                 printf("RETRY WITH NEW LAG LEAD CHOICE=%0.1f\n",Laglead);
                 Bwincrease=1;
                 Lagleadcalc();
                 retrychar++;
             }
         }


     if (I>500)
     {
         printf("!! Error REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT! <-8 dB too far out!\n");
     }


     Count=0;
     Maxx=-20000;
     I_8db=I;
     for (I=I_8db;I<=I_8db+495;I=I+5)
     {
       Count=Count+1;
       Y[Count]=(Display[I]+Display[I+1]+Display[I+2]+Display[I+3]+Display[I+4])/50;
       X[Count]=(I+2)*Hzpbin;
//       IF (Pdv=9836 AND (NOT (No_look))) THEN PLOT LGT(X(Count)),Y(Count)
       Maxx=FNMax(Y[Count]*10,Maxx);
       if  (Maxx==Y[Count]*10) {Maxindex=Count;}
     //  printf("%0.2f %0.2f\n",X[Count],Y[Count]);
     }
     Count=FNMin((Count),(Maxindex+10));
    }  //end of the 3585a function


//16393 ! DEALLOCATE Display(*)
//16396    IF Pdv<>9836 OR (No_look) THEN Curvesmoothing
//16399    FOR I=I TO 1000 STEP 4
//16402       PLOT LGT(I*Hzpbin),Display(I)/10,1
//16405    NEXT I
      //end of the 3585a function

  } while (retrychar==1);

      //This function is common tp 3585a and 3562a data!!

      if (Maxx>(10*10)) {  printf("!! Error: Peak > 10 dB!!\n");}  //ABORT IF PEAK > 10 dB
      if (Maxindex==0)  {  printf("!! Error: Charloop: No data to fit!!\n");}//ABORT IF NO DATA

      printf("CALCULATING PRELIMINARY CURVE FIT FOR CLOSED LOOP RESPONSE\n");

//   ! Fit curve from -8 dB point to just past peak of xfer fn
      curvefit(X,Y,Count,5,&C1,&C2,&C3,&C4,&C5);

//16432    IF Pdv<>9836 OR (No_look) THEN Skipfittedplot
//16435    PENUP
//16438    FOR I=1 TO Count STEP 2
//16441       PLOT LGT(X(I)),C5/X(I)+C1+X(I)*(C2+X(I)*(C3+X(I)*C4)),1
//16444    NEXT I
//16447 Skipfittedplot:!

//   ! Pick N fitted points to do differential correction with
    N=4;
    Y[1]=C5/X[1]+C1+X[1]*(C2+X[1]*(C3+X[1]*C4));
    for (I=2;I<=N;I++)
    {
       X[I]=X[(int)pow(10,(log10(Maxindex)*(double)I/(double)N))]; // !X[10^((I-1)/(N-1))*Maxindex/10];

       Y[I]=C5/X[I]+C1+X[I]*(C2+X[I]*(C3+X[I]*C4));

    }

    for (I=1;I<=N;I++)
    {
       printf("fitted point: %0.2f %0.2f\n",X[I],Y[I]);
    }

//16474    IF Pdv<>9836 OR No_look THEN Skipstars
//16477    PENUP
//16480    FOR I=1 TO N
//16483       MOVE LGT(X(I))-.3,Y(I)
//16486       LABEL USING "K";"*->"
//16489    NEXT I
//16492 Skipstars:       !

    Oldloopbw1=Loopbw1;
    printf("CALCULATING FINAL CURVE FIT FOR CLOSED LOOP RESPONSE\n");

//16504   ! Find values for W1 AND Loopbw1 to match Xfer Fn

   // Difcorrection(X,Y,N,W1,W2,W3,Loopbw1,Maxpointerror);
    Difcorrection(N);

/*16510    DISP
16513    IF Pdv<>9836 OR (No_look) THEN Getvcoindex
16516    PENUP
16519    ALPHA OFF
16522    GRAPHICS ON
16525    RAD
16528    Hzpbin2=Loopbw3*10/125
16531    FOR Binn=1 TO 127
16534       Wi=2*PI*Hzpbin2*Binn
16537       Fw=FNW(Wi,W1,W2,W3,Loopbw1)
16540       PLOT LGT(Wi/(2*PI)),Fw,1
16543    NEXT Binn
16546    GRAPHICS ON
16549    OUTPUT Printer;10^Beginexp;" Hz TO ";10^(Beginexp+4);" Hz"
16552    OUTPUT Printer;"
 1dB PER DIVISION"
16555    GRAPHICS OFF
16558    ALPHA ON
*/

//16567   ! Determine index where vco port must be used

      Getfreqparms(Vcofreq,1000000,&Vcoindex,&I);

      Vcoindex=Vcoindex-1;
      printf("VCOFREQ = %0.1f\n",Vcofreq);
      printf("VCOINDEX = %i\n",Vcoindex);
      Spec=fabs(20.0*log10(Loopbw1/Oldloopbw1));
      Spec=FNMax3(0,Spec-1.0,Maxpointerror-1.0);  //         ! 1 dB in error budget
      printf("Loop BW1 = %0.1f Hz\n",Loopbw1);
      printf("Loop BW1 CHANGE = %0.2f dB\n",20.0*log10(Loopbw1/Oldloopbw1));
      printf("MAX POINT ERROR = %0.2f dB\n",Maxpointerror);


      if (Spec!=0)
      {
         printf("!!WARNING: ACCURACY SPEC MAY BE DEGRADED BY %0.2f dB\n",FNPround(Spec,-2));
      } else
      {
         printf("OK: CHARLOOP ACCURACY IN SPEC (1 dB)!\n");
      }
   /*
16594    IF Spec=0 THEN Charlockcheck
16597    Ans$="Y"
16600    BEEP
16603    DISP "THE ACCURACY SPEC MAY BE DEGRADED BY ";FNPround(Spec,-2);"dB, CONTINUE? (Y/N)";
16606    INPUT Ans$
16609    IF FNUpc$(Ans$[1,1])<>"Y" THEN Abortcharloop4
16612    PRINT "ACCURACY SPEC MAY BE DEGRADED BY ";FNPround(Spec,-2);"dB"
16615   ! PAUSE
16618   ! GOTO Skipstars
16621   ! Check to be sure loop locked back up
16624 Charlockcheck:  !
16627    Toggle("OUT OF LOCK")
16630    Lockcheck(Lockflag)

16633    IF (Abortflag=1) OR (Lockflag=1) THEN Charloopret


16636    BEEP
16639    LOCAL I3582
16642    CLEAR I3585
16645    LOCAL I3585
16648    GRAPHICS OFF
16651    ALPHA ON
16654    DISP "LOCK HAS BEEN LOST, CHECK YOUR SETUP, THEN PRESS 'CONT' TO ZERO THE ""IF"""
16657    BEEP
16660    PAUSE
16663    CALL Walkdownif(Userfrange,10,"LOCKED")        !C start walk X10 up from bottom
16666    Lockcheck(Lockflag)
16669    IF (Abortflag=1) OR (Lockflag=1) THEN Charloopret
16672    GOTO Abortcharloop5
16675 Abrtcharloopkey:   !
16678    DISP "MEASUREMENT ABORTED"
16681    BEEP
16684    WAIT 1.5
16687    GOTO Abortcharloop
16690 Abortcharloop1:    !
16693    DISP "REF 323; UNABLE TO ACHIEVE PHASE LOCK, MEASUREMENT ABORTED ,PRESS 'CONTINUE'."
16696    Errorbeep
16699    PAUSE
16702    GOTO Abortcharloop
16705 Abortcharloop3:  !
16708    DISP "REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT,  PRESS 'CONTINUE'."
16711    Errorbeep
16714    PAUSE
16717    GOTO Abortcharloop
16720 Abortcharloop4:  !
16723    DISP "MEASUREMENT ABORTED BY USER"
16726    BEEP
16729    WAIT 1.5
16732    GOTO Abortcharloop
16735 Abortcharloop5:  !
16738    DISP "REF 318; LOCK HAS BEEN LOST, MEASUREMENT ABORTED, PRESS 'CONTINUE'."
16741    Errorbeep
16744    PAUSE
16747    GOTO Abortcharloop
16750 Abortcharloop6:  !
16753    DISP "REF 320; EXTERNAL LAG-LEAD MUST BE USED, SEE MANUAL FOR DETAILS, PRESS 'CONT'"
16756    Errorbeep
16759    PAUSE
16762    GOTO Abortcharloop
16765 Abortcharloop:    !
16768    Abortflag=1
16771 Charloopret:    !
16774    IF Printer=1 THEN Printer=0
16777    SUBEXIT !  **FF**

16780 Lagleadcalc:  !
16783    W2=2*PI*Zerofreq(Laglead)
16786    W3=1/(R25*C8+1/W2)
16789    Loopbw3=Loopbw1*W3/W2
16792   !
16795   ! Check to see if open loop bw is less than lag-lead pole freq W3
16798    IF Loopbw1<W3/(2*PI) THEN Loopbw3=Loopbw1
16801   !
16804   ! Check to see if open loop bw is >= than pole-freq W3 and less than
16807   ! lag-lead zero freq W2
16810    IF (Loopbw1>=W3/(2*PI)) AND (Loopbw1<W2/(2*PI)) THEN Loopbw3=SQR(Loopbw1*W3/(2*PI))
16813    IF No_look THEN Skiplook5
16816    OUTPUT Printer;"LAG LEAD=";Laglead
16819    OUTPUT Printer;"LOOP BANDWIDTH=";Loopbw3
16822 Skiplook5:  !
16825    IF Laglead=0 THEN CALL Setupinterface("-S4")
16828    IF Laglead<>0 THEN CALL Setupinterface("S4")
16831    Setupbits("LLG",Laglead)
16834    IF Loopbw3>20 THEN CALL Setupinterface("-L0,L9,-S1,-S5,K7,K6,S2")
16837    IF Loopbw3<=20 THEN CALL Setupinterface("L0,-L9,S1,S5,-K7,-K6,-S2")
16840    IF (Loopbw3>250000) AND (Laglead<>7) THEN Abortflag=1
16843    PRINT "LOOP BANDWIDTH=";FNPround(Loopbw3,-2);"Hz"
16846    Vcofreq=Loopbw3/4
16849    RETURN
16852 SUBEND    ! **FF**** */

}



/*
15292 SUBEND    ! **FF**
15295   ! *
15298   ! * NAME: Charloop
15301   ! *
15304   ! * FUNCTION: Calculate which lead lag filter to use.
15307   ! *
15310   ! * INPUT:  Vnom, Vrange, Atten1, Atten2, Phaseslope, Vpeak, Vcoslope,
15313   ! *         Pdv, Caldata(*)
15316   ! *
15319   ! * OUTPUT: Loopbw1, Loopbw3, W1, W2, W3, Laglead, Vcofreq, Vcoindex,
15322   ! *         Spec
15325   ! *
15328 Charloop:  !
15331 SUB Charloop(REAL Vnom,Vrange,Atten1,Atten2,Phaseslope,Vpeak,Vcoslope,Loopbw1,Loopbw3,W1,W2,W3,Vcofreq,Caldata(*),Spec,INTEGER Pdv,Vcoindex)
15334    COM /Loc_flags/ INTEGER C9835,I3582,I3585,I35601a,Clock,Plotter,Abortflag,Printer
15337    COM /Settings/ Latch(0:9)
15340    DIM Ans$[3]                 !Answer to yes/no questions
15343    INTEGER Beginexp            !Used to scale graph
15346    INTEGER Binn                !Bin # of display
15349    INTEGER Bwincrease          !0=ok to increase bandwidth, 1=already increased
15352    REAL C1,C2,C3,C4,C5         !Curve fit coeffecients
15355    REAL C8                     !Capacitor in lag-lead
15358    REAL Corner                 !Freq of pole in lag-lead
15361    INTEGER Count               !Index counter
15364    REAL Fw                     !Value of transfer function at w
15367    REAL Gain                   !Amount of gain in programmable gains
15370    REAL Gain1                  !0->28 dB in 4 dB steps
15373    REAL Gain2                  !6->20 dB in 2 dB steps
15376    REAL Hzpbin                 !Hz per display bin
15379    REAL Hzpbin2                !Hz per bin used for plot of loop
15382    INTEGER I                   !For-next loop counter
15385    INTEGER J                   !For-next loop counter
15388    REAL Junk                   !Dummy variable for non-usable value read from the 3585A
15391    REAL Laglead2               !Effective Lag-lead if external lag-lead used
15394    INTEGER Lockflag            !0=loop not locked, 1=loop locked
15397    REAL Loopbw2                !
15400    INTEGER Maxindex            !Index where max response occured
15403    REAL Maxpointerror          !Max error determined by Difcorrection
15406    REAL Maxx                   !Value of max response
15409    INTEGER N                   !Number of points for differential correction
15412    INTEGER Numsamples          !Number of samples on 3582A XFER function
15415    REAL Oldloopbw1             !Initial calculation of Loopbw1
15418    REAL R25                    !Resistor in lag-lead
15421    REAL Rc2pi                  !Product of 2*PI*R*C
15424    INTEGER Sens                !Sensitivity setting of the 3582A
15427    INTEGER Span                !Span number of the 3582A
15430    INTEGER Stat                !Status read from the 3582A or 3585A
15433    REAL Wi                     !Radian freq
15436    REAL X(1:100)               !Freq's to be used for curve fit
15439    REAL X1                     !Freq to be put in X(*)
15442    REAL Y(1:100)               !Amp's to be used for curve fit
15445    REAL Zero                   !Desired Leadfreq in lag-lead
15448    REAL Zerofreq(0:11)         !Actual Leadfreqs for each lag-lead
15451                                ! Plus 4 EXTERNAL lag-leads
15454    No_look=1 !SET No_look=0 TO PLOT LOOP SUPPRESSION, =1 TO NOT PLOT.
15457    ON KEY 19 LABEL "ABORT FUNCTION",3 GOTO Abrtcharloopkey
15460    ENABLE
15463    DISP CHR$(130)&CHR$(127)&CHR$(128)&"CALCULATING PHASE LOCK LOOP PARAMETERS"
15466   !
15469   ! Zero freqs are calculated from the resistor selected by
15472   ! the following formula:   f=1/(2*PI*(R+100)*C8)
15475   ! 100 is the switch resistance
15478   !
15481    DATA 9.95,40.1,115.9,306,784,1.985E3,5E3,12.58E3,31612,79421,199511,501164
15484    READ Zerofreq(*)
15487    C8=3.3E-8                 ! .033 uf
15490    R25=4.823E+5              ! 482K ohm
15493    CLEAR I3585
15496   !
15499   ! DETERMINE GAIN SETTINGS
15502    Gain=2*(20*LGT(Vrange/Atten1/Vpeak) DIV 2)
15505    IF Gain>54 THEN Gain=54
15508    Loopbw1=ABS(Phaseslope*Vcoslope*10^(Gain/20)) ! OPEN LOOP BW
15511    Loopbw1=Loopbw1/10^(FNCalpoint(0,0,Mixerfreq,Caldata(*),0,0,0,0,0,0,10000)/20)      ! ADJUST PHASESLOPE TO MEASUREMENT POINT
15514    Gain=Gain-12+6            !TAKE OUT x4(12dB) AMPLIFIER AND 6dB PAD
15517    Gain=Gain+6*(Atten2=.5)   !ADD 6 dB IF ATTEN2=.5
15520    Gain2=20-Gain MOD 4       !CHOOSE 20 OR 18 dB FOR GAIN2
15523    IF Gain<18 THEN Gain2=Gain!USE LESS IF GAIN<18
15526    Gain2=FNMax(6,Gain2)        !GAIN2 HAS 6 dB MIN
15529    Gain1=Gain-Gain2          !PUT REMAINING GAIN IN GAIN1
15532    Setupbits("GN1",Gain1)
15535    Setupbits("GN2",Gain2)
15538    Setupbits("DAC",Vnom/Atten1)
15541    Setupinterface("L2,K10,S3")   ! CLOSE LOOP
15544    IF Printer=0 THEN Printer=1
15547    IF No_look THEN Skiplook
15550    DISABLE
15553    PRINTER IS Printer
15556    PRINT "GAIN=";Gain
15559    PRINT "VCOSLOPE=";Vcoslope/Atten1;" Hz/V"
15562    PRINT "PHASESLOPE=";Phaseslope
15565    PRINT "VPEAK= ";Vpeak
15568    PRINT "LOOP BW1=",Loopbw1
15571    ENABLE
15574 Skiplook: !
15577   !
15580   ! Calculate BW assuming far out zero
15583    Corner=1/(2*PI*R25*C8)
15586    Loopbw2=SQR(Loopbw1*Corner)! Geometric mean, approximate cross-over
15589   !
15592   ! DETERMINE WHICH ZERO TO USE
15595    Zero=Loopbw2/2^.5
15598    FOR Laglead=11 TO 0 STEP -1
15601       IF Zerofreq(Laglead)<Zero THEN Lagleadfound
15604    NEXT Laglead
15607    Laglead=0
15610 Lagleadfound:    !
15613    IF No_look THEN Skip_look1
15616    PRINTER IS Printer
15619    PRINT "INITIAL LAG LEAD CHOICE=";Laglead
15622    PRINT "NEEDED ZERO FREQ=";Zero
15625    PRINT "ACTUAL ZERO FREQ=";Zerofreq(Laglead)
15628    PRINTER IS 1
15631    PRINT
15634 Skip_look1:  !
15637   !
15640    Laglead2=Laglead
15643    Bwincrease=0
15646    IF Laglead>7 THEN Abortcharloop6
15649    GOTO Noexternal  ! COMMENT FOR EXTERNAL LAG-LEAD **********
15652    Ans$="N"
15655    BEEP
15658    INPUT "DO YOU HAVE AN EXTERNAL PHASE LEAD (Y/N)",Ans$
15661    IF FNUpc$(Ans$[1;1])<>"Y" THEN Noexternal
15664 Getlaglead:  !
15667    BEEP
15670    INPUT "ENTER LAG-LEAD FOR 35601A HARDWARE (0-7)",Laglead2
15673    Laglead2=INT(Laglead2)
15676    IF (Laglead2>=0) AND (Laglead2<=7) THEN Geteffective
15679    PRINT CHR$(27)&"A"&CHR$(27)&"J"&"LAG LEAD NUMBER MUST BE 0-7"
15682    Errorbeep
15685    GOTO Getlaglead
15688 Geteffective: !
15691    Laglead=Laglead2
15694    DISP "ENTER EFFECTIVE LAG-LEAD NUMBER (";Laglead2;"- 11 )";
15697    BEEP
15700    INPUT Laglead
15703    Laglead=INT(Laglead)
15706    IF (Laglead>=Laglead2) AND (Laglead<=11) THEN Lagleadsok
15709    PRINT CHR$(27)&"A"&CHR$(27)&"J"&"LAG LEAD NUMBER MUST BE";Laglead2;"- 11"
15712    Errorbeep
15715    GOTO Geteffective
15718 Lagleadsok:  !
15721    GOSUB Lagleadcalc
15724    IF Abortflag<>0 THEN Abortcharloop1
15727    Bwincrease=1       ! DON'T ALLOW LAGLEAD TO BE CHANGED
15730    Setupbits("LLG",Laglead2)! FORCE LAGLEAD2
15733    GOTO Checklock
15736 Noexternal:  !
15739    GOSUB Lagleadcalc
15742    IF Abortflag<>0 THEN Abortcharloop1
15745   ! CHECK TO SEE IF LOOP IS LOCKED
15748 Checklock:  !
15751    ENABLE
15754    PRINTER IS 1
15757    Lockcheck(Lockflag)
15760    IF Abortflag=1 THEN Abortcharloop
15763    IF Lockflag=1 THEN Startcharloop
15766   ! IF NOT LOCKED, TRY TO INCREASE LOOP BANDWIDTH
15769 Increaseloopbw:  !
15772    IF (Bwincrease=1) OR (Laglead=0) THEN Abortcharloop1
15775    Laglead=Laglead-1 !INCREASE LOOP BANDWIDTH
15778    Bwincrease=1
15781    DISABLE
15784    GOSUB Lagleadcalc   !CALCULATE ACTUAL LOOP BW
15787    IF Abortflag<>0 THEN Abortcharloop1
15790    ENABLE
15793    GOTO Checklock
15796   !
15799 Startcharloop:         !
15802    IF No_look THEN Skipplot
15805    IF Pdv<>9836 THEN Skipplot
15808    GINIT
15811    GCLEAR
15814    PEN 1
15817    GRAPHICS ON
15820    Beginexp=INT(LGT(Loopbw3)-2)
15823   !
15826    VIEWPORT 0,100,10,100
15829    LORG 5
15832    CSIZE 3,.6
15835    MOVE 70,95
15838    LABEL USING "#,K";"THEORETICAL & ACTUAL 'LOOP SUPPRESSION' FACTORS"
15841   !
15844    VIEWPORT 0,100,20,90
15847    WINDOW Beginexp,Beginexp+4,-10,10
15850    LINE TYPE 4,.30
15853    GRID 1,1,Beginexp,0
15856    LINE TYPE 1
15859    FRAME
15862    PENUP
15865 Skipplot:      !
15868   !
15871   ! USE 3585A FOR LOOP BANDWIDTHS >20 HZ
15874    GRAPHICS OFF
15877    IF Loopbw3>=20 THEN Charloop85
15880    Setupinterface("L0,-L9")
15883    Span=14
15886    Hzpbin=25000/125
15889    IF Loopbw3<3000 THEN Span=13
15892    IF Loopbw3<3000 THEN Hzpbin=10000/125
15895    IF Loopbw3<1500 THEN Span=12
15898    IF Loopbw3<1500 THEN Hzpbin=5000/125
15901    IF Loopbw3<750 THEN Span=11
15904    IF Loopbw3<750 THEN Hzpbin=2500/125
15907    IF Loopbw3<300 THEN Span=10
15910    IF Loopbw3<300 THEN Hzpbin=1000/125
15913    IF Loopbw3<150 THEN Span=9
15916    IF Loopbw3<150 THEN Hzpbin=500/125
15919    IF Loopbw3<75 THEN Span=8
15922    IF Loopbw3<75 THEN Hzpbin=250/125
15925    IF Loopbw3<30 THEN Span=7
15928    IF Loopbw3<30 THEN Hzpbin=100/125
15931    IF Loopbw3<15 THEN Span=6
15934    IF Loopbw3<15 THEN Hzpbin=50/125
15937    IF Loopbw3<7.5 THEN Span=5
15940    IF Loopbw3<7.5 THEN Hzpbin=25/125
15943    IF Loopbw3<3 THEN Span=4
15946    IF Loopbw3<3 THEN Hzpbin=10/125
15949    IF Loopbw3<.5 THEN Span=1
15952    IF Loopbw3<.5 THEN Hzpbin=1/125
15955    Numsamples=15*Hzpbin
15958    Numsamples=FNMin((Numsamples),30)
15961    Numsamples=FNMax((Numsamples),4)
15964    OUTPUT I3582;"PRS,AC2,BC2"
15967    Toggle("AC DC")
15970    Sens=5
15973    Autorange82(Sens)
15976    IF Abortflag=1 THEN Charloopret
15979    Sens=FNMax(2,(Sens-1))
15982 Format:IMAGE "PRS AA0 RP0 IM2 AC2 BC2 BS",2D,"AM",DD,"AS4 MD2 PS3 AV2 NU4 SP",2D,"AX1REWTM,77465,1",/,W,"LST0"
15985    IF No_look THEN Skiplook3
15988    OUTPUT I3582 USING Format;Sens,FNMin(9,9-(Sens-4)),Span,Numsamples
15991    OUTPUT I3582;"RP1"
15994    PRINT TABXY(1,17);" OBSERVE 3582 DISPLAY OF LOOP SUPRESSION CHARACTERISTIC. "
15997    PRINT TABXY(1,18);" EXCESSIVE NOISE MAY CAUSE ACCURACY SPEC DEGRADATION     "
16000    BEEP
16003    INPUT "CHECK LOOP SUPPRESSION ON 3582A, THEN PRESS 'CONT';ENTER 'S' FOR 'SWITCH'",Trble$
16006   !
16009    PRINT TABXY(1,17);FNClte$
16012    PRINT TABXY(1,18);FNClte$
16015   !
16018    IF Trble$="S" THEN CALL Switch
16021 Skiplook3:  !
16024    DISP CHR$(130)&CHR$(127)&CHR$(128)&"WAITING FOR AVERAGING ON 3582A OF CLOSED LOOP RESPONSE"
16027    OUTPUT I3582 USING Format;Sens,FNMin(9,9-(Sens-4)),Span,Numsamples
16030    ENTER I3582 USING "#,B";Stat
16033    Toggle("OUT OF LOCK")
16036    OUTPUT I3582;"RP1"
16039 Loop:OUTPUT I3582;"LST1"
16042    ENTER I3582 USING "#,B";Stat
16045    IF BIT(Stat,6)=0 THEN Loop
16048    Setupinterface("-S1,-L0,L9")
16051    DISP CHR$(130)&CHR$(127)&CHR$(128)&"MEASURING CLOSED LOOP RESPONSE"
16054    ALLOCATE Display(0:127)
16057    OUTPUT I3582;"LFM,74600,128"
16060    ENTER I3582 USING "#,W";Display(127)      ! Get first value so don't
16063    Display(127)=BINAND(Display(127),1023)    ! need hpip address each time
16066    FOR I=126 TO 0 STEP -1
16069       ENTER I3582 USING "#,W";Display(I)
16072       Display(I)=BINAND(Display(I),1023)
16075    NEXT I
16078    Mat1(Display(*),"*",(10*80/1023),0,127)  !SCALE FROM 0 TO 800
16081   !
16084   ! Assume transfer function is 0 far out
16087    Mat1(Display(*),"-",((Display(123)+Display(124)+Display(125))/3),0,127)
16090    Rc2pi=1.E+5*1.0E-5*2*PI
16093    FOR I=1 TO 127         !CORRECTION FOR (1/(1+1/RCs))  AC COUPLER
16096       Display(I)=Display(I)+10*10*LGT(1+1/(Rc2pi*I*Hzpbin)^2)
16099       IF (Pdv=9836 AND (NOT (No_look))) THEN PLOT LGT(I*Hzpbin),Display(I)/10,1
16102    NEXT I
16105    Maxx=-20000
16108   ! FIND FIRST POINT < -8 dB
16111    FOR I=100 TO 2 STEP -1
16114       IF (Display(I)<-80) AND (Display(I-1)<-80) THEN Found8db
16117       Maxx=FNMax((Display(I)),(Maxx))
16120       IF Maxx=Display(I) THEN Maxindex=I
16123    NEXT I
16126   ! TRY TO INCREASE LOOP BANDWIDTH IF -8 dB POINT NOT FOUND
16129    DEALLOCATE Display(*)
16132    IF (Bwincrease=1) OR (Laglead=0) THEN Abortcharloop3
16135    Bwincrease=1
16138    Laglead=Laglead-1
16141    GOSUB Lagleadcalc
16144    IF Abortflag<>0 THEN Abortcharloop1
16147    GOTO Startcharloop
16150 Found8db:  !
16153    Count=0
16156    FOR J=I TO FNMin(Maxindex+5,100)
16159       Count=Count+1
16162       Y(Count)=Display(J)/10
16165       X(Count)=J*Hzpbin
16168    NEXT J
16171    Maxindex=Maxindex-I+1
16174    GOTO Curvesmoothing
16177   !
16180 Charloop85:    !
16183    Hzpbin=(Loopbw3*4 DIV 10)*.01 ! Span=BW3*4. Hzpbin in Units of .01 Hz.
16186    CLEAR I3585 ! CLEAR DISPLAY BITS
16189    OUTPUT I3585 USING "K,8D.D,K";"FB",1000*Hzpbin,"HZ,R10,I1,SV4,S2"
16192    IF No_look THEN Skiplook4
16195    OUTPUT I3585;"SV1 S1"
16198    LOCAL I3585
16201    BEEP
16204   !
16207    PRINT TABXY(1,17);" OBSERVE 3585 DISPLAY OF LOOP SUPRESSION CHARACTERISTIC. "
16210    PRINT TABXY(1,18);" EXCESSIVE NOISE MAY CAUSE ACCURACY SPEC DEGRADATION     "
16213   !
16216    BEEP
16219    INPUT "CHECK LOOP SUPPRESSION ON 3585A, THEN PRESS 'CONT';ENTER 'S' FOR 'SWITCH'",Trble$
16222   !
16225    PRINT TABXY(1,17);FNClte$
16228    PRINT TABXY(1,18);FNClte$
16231   !
16234    IF Trble$="S" THEN CALL Switch
16237    CLEAR I3585
16240    OUTPUT I3585;"RC1"
16243 Skiplook4:  !
16246    Toggle("OUT OF LOCK")
16249    DISP CHR$(130)&CHR$(127)&CHR$(128)&"MEASURING CLOSED LOOP RESPONSE"
16252    WAIT 1
16255    OUTPUT I3585;"S2" !Start the sweep
16258   !
16261 Waitforsweep:OUTPUT I3585;"D6T4"
16264    ENTER I3585 USING "#,B";Stat
16267    IF BIT(Stat,7) THEN Waitforsweep
16270   !
16273    OUTPUT I3585;"SAAB1"
16276    Setupinterface("-S3,-S4")  ! Open loop for reference sweep
16279    OUTPUT I3585;"S2"               !Start the sweep
16282   !
16285 Waitforsweep2:OUTPUT I3585;"D6T4"
16288    ENTER I3585 USING "#,B";Stat
16291    IF BIT(Stat,7) THEN Waitforsweep2
16294   !
16297    Setupinterface("-K7,-K6,-S2,S3,S4")!Close loop again
16300    ALLOCATE Display(0:1000)
16303    OUTPUT I3585;"C5CLSABO"
16306    ENTER I3585 USING "#,W";Junk            !First two bytes are junk
16309    ENTER I3585 USING "#,W";Display(*)
16312    Display(1000)=BINAND(Display(1000),1023)
16315    Display(0)=BINAND(Display(0),1023)
16318    FOR I=0 TO 1000
16321       Display(I)=500-Display(I)!SCALE FROM -500 TO 500
16324    NEXT I
16327    IF Display(1000)<-10 THEN Abortcharloop3!Check for < -1 dB far out
16330    FOR I=1000 TO 2 STEP -1                 !Search for first point <-8 dB
16333       IF (Display(I)<-80) AND (Display(I-1)<-80) THEN Found08db
16336    NEXT I
16339    GOTO Abortcharloop3
16342 Found08db:    ! -8 dB point found, increase loop bandwidth if invalid
16345    IF (I>500) AND (Bwincrease=0) THEN
16348       DEALLOCATE Display(*)
16351       GOTO Increaseloopbw
16354    END IF
16357    IF I>500 THEN Abortcharloop3
16360    Count=0
16363    Maxx=-20000
16366    FOR I=I TO I+495 STEP 5
16369       Count=Count+1
16372       Y(Count)=(Display(I)+Display(I+1)+Display(I+2)+Display(I+3)+Display(I+4))/50
16375       X(Count)=(I+2)*Hzpbin
16378       IF (Pdv=9836 AND (NOT (No_look))) THEN PLOT LGT(X(Count)),Y(Count)
16381       Maxx=FNMax(Y(Count)*10,Maxx)
16384       IF Maxx=Y(Count)*10 THEN Maxindex=Count
16387    NEXT I
16390    Count=FNMin((Count),(Maxindex+10))
16393 ! DEALLOCATE Display(*)
16396    IF Pdv<>9836 OR (No_look) THEN Curvesmoothing
16399    FOR I=I TO 1000 STEP 4
16402       PLOT LGT(I*Hzpbin),Display(I)/10,1
16405    NEXT I
16408   !
16411 Curvesmoothing:  !
16414    IF Maxx>10*10 THEN Abortcharloop3  !ABORT IF PEAK > 10 dB
16417    IF Maxindex=0 THEN Abortcharloop3  !ABORT IF NO DATA
16420    DISP CHR$(130)&CHR$(127)&CHR$(128)&"CALCULATING PRELIMINARY CURVE FIT FOR CLOSED LOOP RESPONSE"
16423   !
16426   ! Fit curve from -8 dB point to just past peak of xfer fn
16429    Curvefit(X(*),Y(*),Count,5,C1,C2,C3,C4,C5)
16432    IF Pdv<>9836 OR (No_look) THEN Skipfittedplot
16435    PENUP
16438    FOR I=1 TO Count STEP 2
16441       PLOT LGT(X(I)),C5/X(I)+C1+X(I)*(C2+X(I)*(C3+X(I)*C4)),1
16444    NEXT I
16447 Skipfittedplot:!
16450   !
16453   ! Pick N fitted points to do differential correction with
16456    N=4
16459    Y(1)=C5/X(1)+C1+X(1)*(C2+X(1)*(C3+X(1)*C4))
16462    FOR I=2 TO N
16465       X(I)=X(10^(LGT(Maxindex)*I/N))!X(10^((I-1)/(N-1))*Maxindex/10)
16468       Y(I)=C5/X(I)+C1+X(I)*(C2+X(I)*(C3+X(I)*C4))
16471    NEXT I
16474    IF Pdv<>9836 OR No_look THEN Skipstars
16477    PENUP
16480    FOR I=1 TO N
16483       MOVE LGT(X(I))-.3,Y(I)
16486       LABEL USING "K";"*->"
16489    NEXT I
16492 Skipstars:       !
16495    Oldloopbw1=Loopbw1
16498    DISP CHR$(130)&CHR$(127)&CHR$(128)&"CALCULATING FINAL CURVE FIT FOR CLOSED LOOP RESPONSE"
16501   !
16504   ! Find values for W1 AND Loopbw1 to match Xfer Fn
16507    Difcorrection(X(*),Y(*),N,W1,W2,W3,Loopbw1,Maxpointerror)
16510    DISP
16513    IF Pdv<>9836 OR (No_look) THEN Getvcoindex
16516    PENUP
16519    ALPHA OFF
16522    GRAPHICS ON
16525    RAD
16528    Hzpbin2=Loopbw3*10/125
16531    FOR Binn=1 TO 127
16534       Wi=2*PI*Hzpbin2*Binn
16537       Fw=FNW(Wi,W1,W2,W3,Loopbw1)
16540       PLOT LGT(Wi/(2*PI)),Fw,1
16543    NEXT Binn
16546    GRAPHICS ON
16549    OUTPUT Printer;10^Beginexp;" Hz TO ";10^(Beginexp+4);" Hz"
16552    OUTPUT Printer;"
 1dB PER DIVISION"
16555    GRAPHICS OFF
16558    ALPHA ON
16561 Getvcoindex:      !
16564   !
16567   ! Determine index where vco port must be used
16570    Getfreqparms(Vcofreq,1000000,Vcoindex,I)
16573    Vcoindex=Vcoindex-1
16576    Spec=ABS(20*LGT(Loopbw1/Oldloopbw1))
16579    Spec=FNMax(0,Spec-1.,Maxpointerror-1.)          ! 1 dB in error budget
16582    IF No_look THEN Skiplook6
16585    OUTPUT Printer;"BW1 CHANGE=";20*LGT(Loopbw1/Oldloopbw1)
16588    OUTPUT Printer;"MAX POINT ERROR=";Maxpointerror
16591 Skiplook6:    !
16594    IF Spec=0 THEN Charlockcheck
16597    Ans$="Y"
16600    BEEP
16603    DISP "THE ACCURACY SPEC MAY BE DEGRADED BY ";FNPround(Spec,-2);"dB, CONTINUE? (Y/N)";
16606    INPUT Ans$
16609    IF FNUpc$(Ans$[1,1])<>"Y" THEN Abortcharloop4
16612    PRINT "ACCURACY SPEC MAY BE DEGRADED BY ";FNPround(Spec,-2);"dB"
16615   ! PAUSE
16618   ! GOTO Skipstars
16621   ! Check to be sure loop locked back up
16624 Charlockcheck:  !
16627    Toggle("OUT OF LOCK")
16630    Lockcheck(Lockflag)
16633    IF (Abortflag=1) OR (Lockflag=1) THEN Charloopret
16636    BEEP
16639    LOCAL I3582
16642    CLEAR I3585
16645    LOCAL I3585
16648    GRAPHICS OFF
16651    ALPHA ON
16654    DISP "LOCK HAS BEEN LOST, CHECK YOUR SETUP, THEN PRESS 'CONT' TO ZERO THE ""IF"""
16657    BEEP
16660    PAUSE
16663    CALL Walkdownif(Userfrange,10,"LOCKED")        !C start walk X10 up from bottom
16666    Lockcheck(Lockflag)
16669    IF (Abortflag=1) OR (Lockflag=1) THEN Charloopret
16672    GOTO Abortcharloop5
16675 Abrtcharloopkey:   !
16678    DISP "MEASUREMENT ABORTED"
16681    BEEP
16684    WAIT 1.5
16687    GOTO Abortcharloop
16690 Abortcharloop1:    !
16693    DISP "REF 323; UNABLE TO ACHIEVE PHASE LOCK, MEASUREMENT ABORTED ,PRESS 'CONTINUE'."
16696    Errorbeep
16699    PAUSE
16702    GOTO Abortcharloop
16705 Abortcharloop3:  !
16708    DISP "REF309;UNABLE TO GET A VALID XFER FUNCTION FOR MEASUREMENT,  PRESS 'CONTINUE'."
16711    Errorbeep
16714    PAUSE
16717    GOTO Abortcharloop
16720 Abortcharloop4:  !
16723    DISP "MEASUREMENT ABORTED BY USER"
16726    BEEP
16729    WAIT 1.5
16732    GOTO Abortcharloop
16735 Abortcharloop5:  !
16738    DISP "REF 318; LOCK HAS BEEN LOST, MEASUREMENT ABORTED, PRESS 'CONTINUE'."
16741    Errorbeep
16744    PAUSE
16747    GOTO Abortcharloop
16750 Abortcharloop6:  !
16753    DISP "REF 320; EXTERNAL LAG-LEAD MUST BE USED, SEE MANUAL FOR DETAILS, PRESS 'CONT'"
16756    Errorbeep
16759    PAUSE
16762    GOTO Abortcharloop
16765 Abortcharloop:    !
16768    Abortflag=1
16771 Charloopret:    !
16774    IF Printer=1 THEN Printer=0
16777    SUBEXIT !  **FF**
16780 Lagleadcalc:  !
16783    W2=2*PI*Zerofreq(Laglead)
16786    W3=1/(R25*C8+1/W2)
16789    Loopbw3=Loopbw1*W3/W2
16792   !
16795   ! Check to see if open loop bw is less than lag-lead pole freq W3
16798    IF Loopbw1<W3/(2*PI) THEN Loopbw3=Loopbw1
16801   !
16804   ! Check to see if open loop bw is >= than pole-freq W3 and less than
16807   ! lag-lead zero freq W2
16810    IF (Loopbw1>=W3/(2*PI)) AND (Loopbw1<W2/(2*PI)) THEN Loopbw3=SQR(Loopbw1*W3/(2*PI))
16813    IF No_look THEN Skiplook5
16816    OUTPUT Printer;"LAG LEAD=";Laglead
16819    OUTPUT Printer;"LOOP BANDWIDTH=";Loopbw3
16822 Skiplook5:  !
16825    IF Laglead=0 THEN CALL Setupinterface("-S4")
16828    IF Laglead<>0 THEN CALL Setupinterface("S4")
16831    Setupbits("LLG",Laglead)
16834    IF Loopbw3>20 THEN CALL Setupinterface("-L0,L9,-S1,-S5,K7,K6,S2")
16837    IF Loopbw3<=20 THEN CALL Setupinterface("L0,-L9,S1,S5,-K7,-K6,-S2")
16840    IF (Loopbw3>250000) AND (Laglead<>7) THEN Abortflag=1
16843    PRINT "LOOP BANDWIDTH=";FNPround(Loopbw3,-2);"Hz"
16846    Vcofreq=Loopbw3/4
16849    RETURN
16852 SUBEND    ! **FF****
*/


double Freq1;                 // !Freq of first bin of 3585A display
double Freq2;                 // !Freq of 2nd bin of 3585A display
int Path;              //  !Number of the current path being checked
double Maxcorr;              //  !Max correction for a particular segment
double Maxerror;             //  !Max fit error for a particular segment
double Overallmaxcorr;        // !Max of all Maxcorr
double Overallmaxerror;      //  !Max of all Maxerror


void Calpath(void)
{
    int Display[1010]; //(-1:1000)  //

     int Reflevel;          //  !Reference level of 3585A
     int Count;             //  !Counter
    double F[100];               // !Freq's for curve fit
    double Freq;                 //  !Freq
    double Hzpbin;                // !Hz per display bin
    int I;                 //  !For-next loop counter
    int J;                  // !For-next loop counter
    int Start;             //  !Bin of display where calibration starts
    double Y[100];              //  !Amplitude for each Frequency in F(*)
    double Correction;


     w3585("MK1D2T4");
     r3585(12);
     //intf(">%s<",Buffer);
     Freq1=atof(Buffer);
     w3585("MK2D2T4");
     r3585(12);
     //intf(">%s<",Buffer);
     Freq2=atof(Buffer);
     //printf("Path: %d, Freq %0.1f  Freq2 %0.1f\n",Path,Freq1,Freq2);

     w3585("AB1 C5CL SA AB0 TA0 BO");
     rd3585();

     for (I=0;I<1001;I++)
     {
         Display[I]=Display3585[I+1]; //first bit is ffff
     }
     Display[0]=Display[0]&1023;
     Display[1000]=Display[1000]&1023;
     Reflevel=5;
     for (I=0;I<1001;I++)
     {
         Display[I]=Display[I]+(100*(Reflevel-10));
     }
     for (I=0;I<1001;I++)
     {
         Display[I]=Display[I]*(-1);
     }

     Hzpbin=Freq2-Freq1;

     Count=1;
     Start=0;
     if (Path==1) {Start=10;} // ! 2 MHz LPF
     if (Path==2) {Start=100;}
//464    IF (Plotter<>0) OR (C9835=0) THEN PENUP
     Maxcorr=-200;
     Maxerror=-200;
//4473    IF Doplot THEN LINE TYPE 1
     for (I=1;I<=81;I++)
     {
         F[I]=0;
         Y[I]=0;
     }

      for (I=Start;I<=1000;I=I+13)
      {
        Freq=I*Hzpbin+Freq1;
        F[Count]=Freq;
        Y[Count]=((double)Display[I])/100.0;
        Maxcorr=FNMax(fabs(Y[Count]),Maxcorr);
//       IF Doplot THEN PLOT LGT(Freq),Y(Count),1
        Count=Count+1;
      }

//  ! IF PATH=1 THEN ONLY GET 4 2 MHZ FILTER COEFFECIENTS

      if (Path==1)
        {
          curvefit(&F,&Y,Count-1,4,&Caldata[Path][1],&Caldata[Path][2],&Caldata[Path][3],&Caldata[Path][4],&Caldata[Path][5]);
        } else
        {
            curvefit(&F,&Y,Count-1,5,&Caldata[Path][1],&Caldata[Path][2],&Caldata[Path][3],&Caldata[Path][4],&Caldata[Path][5]);
        }

//14512    IF Doplot THEN PENUP
//14515    IF Doplot THEN LINE TYPE 3,.3

      for (I=Start;I<=1000;I=I+25)
      {
        Freq=I*Hzpbin+Freq1;
        Correction=Caldata[Path][1]+Caldata[Path][2]*Freq+Caldata[Path][3]*Freq*Freq+Caldata[Path][4]*Freq*Freq*Freq+Caldata[Path][5]/Freq;
//14527       IF Doplot THEN PLOT LGT(Freq),Correction,1
        Maxerror=FNMax(fabs((double)Display[I]/100.0-Correction),Maxerror);
      }
     Overallmaxcorr=FNMax(Maxcorr,Overallmaxcorr);
     Overallmaxerror=FNMax(Maxerror,Overallmaxerror);

}


char lf3585[2]={10,0};

void Cal(void)
{
double Amp;                 //   !Amplitude of 3585A tracking generator

char tbuf[100];
int levelok;

//    Doplot=0;//    !SET TO 0 TO SUPPRESS PLOT
//    Look=0;//      !SET TO 1 TO LOOK AT INSERTION LOSS


    printf("Calibrating interface box unflatness...\n");
    ibclr(Device3585);                 // Clear the 3585
    if (Ibsta() & ERR) {
      GpibError("ibclr Error");
    }
    wait_s01(3);

//    Mat2(C(*),"*",0,1,7,1,5)

    Caldata[7][1]=0.095;
    Caldata[7][2]=1.65E-8;
    Caldata[7][3]=-4.5E-16;
    Caldata[7][4]=5.75E-24;
    Caldata[7][5]=-5900.0;
    Overallmaxcorr=0.0;
    Overallmaxerror=0.0;
    zerolatch();
    toggle_i(OVERLOAD);
    setup_i("K2,K3,K4,K5,K7");

    w3585("AR0 AL0 RL -49DM DD1DB R01 RC4"); //setup 3585a

    levelok=0;
    do {
        w3585("S2D1T6");

        r3585(13);
        Amp=atof(Buffer);
        printf("3585A Amplitude: %0.1f dBm\n",Amp);

        if (abs(Amp+54)<=1) {levelok=1;} else
          {
            w3585("S1");
            printf("ADJUST 3585A TRACKING GEN FOR CENTER OF 3585A SCREEN, THEN PRESS KEY!\n");
            w3585("LA ADJUST 3585A TRACKING GEN FOR CENTER OF 3585A SCREEN\n");w3585(lf3585);

            getchar();
          }

      }while (!levelok);

       w3585("AL1 R05 FS FA 100000HZ FB 40.1 MZ PR RBDN DD1DB RC4 SV4 DA S1");
       w3585("LA CONNECT TG DIRECTLY TO 50 OHM INPUT");  w3585(lf3585);

       printf("CONNECT 3585A TRACKING GENERATOR OUTPUT DIRECTLY TO 3585A 50 OHM INPUT,\n THEN PRESS KEY!\n");
       getchar();

       w3585("S2 S2");
       waitfor3585();

       Path=7;

       setup_i("-K2,-K3,-K4,-K5,-K7");

       w3585("LACONNECT TG TO 40 MHZ INPUT, RECONNECT 50 OHM INPUT");w3585(lf3585);
       printf("CONNECT TRACKING GEN. TO 35601A SIGNAL INPUT, RECONNECT 50 OHM INPUT OF 3585A,\n THEN PRESS KEY!\n");

       getchar();
       printf("CALIBRATING INSERTION LOSS...\n");

       w3585("SA S2S2");

       waitfor3585();

       Calpath();

       setup_i("K2,K3,K4,K5,K7");
       w3585("AR0 AL0 RL -49DM DD1DB R01 RC4 S2 ");
//14104    OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"INSERTION LOSS",Maxcorr,Maxerror
       printf(">>Insertion Loss %0.3f %0.3f\n\n",Maxcorr,Maxerror);
       printf("RECONNECT 3585A TRACKING GEN. TO 35601A TRACKING GEN. INPUT,\n THEN PRESS KEY!\n");
       w3585("TB0TA1LARECONNECT TRACKING GENERATOR TO PROPER 35601A CONNECTION");w3585(lf3585);

       getchar();

//Path1: !
        printf("CALIBRATING AMPLIFIER FLATNESS; RESULTS ARE [MAXCORR] [MAXERROR]\n");
//  ! CALIBRATE 2 MHZ LOW PASS FILTER ON HF BOARD TO 1MHz
        Path=1;
        setup_i("K1,K12");
        w3585("RL -49DM FA0HZ FB1MZ PR RBDN RC4 SV4 DA S2 S2");
        w3585("LA 2MHZ FILTER IN");w3585(lf3585);
        waitfor3585();
        setup_i("K8"); // !K8 AND K9 MOVE TOGETHER
        w3585("SA S2 S2");
        waitfor3585();

        Calpath();
        printf(">>2 MHz Filter %0.3f %0.3f\n",Maxcorr,Maxerror);

//14161    OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"2 MHz FILTER",Maxcorr,Maxerror

//14167  ! CALIBRATE AMPLIFIER PATH TO 400 HZ
        Path=2;
        setup_i("-K8,-K9");
        w3585("FA5HZ FB405HZ PR RC4 SV4 TB0  S2 S2");
        w3585("LA STRAIGHT THROUGH, AMPLIFIER IN");w3585(lf3585);
        waitfor3585();
        setup_i("K11");
        w3585("RL -15DM SA S2 S2");
        waitfor3585();

        Calpath();
        printf(">>x100 AMP to 400 Hz %0.3f %0.3f\n",Maxcorr,Maxerror);

//14197    OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"x100 AMP TO 400 Hz",Maxcorr,Maxerror

//  ! CALIBRATE AMPLIFIER PATH FROM 400 TO 25000 HZ
        Path=3;
        setup_i("-K11");
        w3585("RL-49DM FA400HZ FB25400HZ PR RBDN RC4 SV4 TB0 S2 S2");
        waitfor3585();

        setup_i("K11");
        w3585("RL -15DM SA S2 S2");
        waitfor3585();

        Calpath();
        printf(">>x100 AMP 400 TO 25 KHz %0.3f %0.3f\n",Maxcorr,Maxerror);


//14230    OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"x100 AMP 400 TO 25 KHz",Maxcorr,Maxerror

//  ! CALIBRATE AMPLIFIER FROM 25000 TO 5 MHz
        Path=4;
        setup_i("-K11");
        w3585("RL -49DM FA 25000HZ FB 5000000  HZ PR RBDN RC4 SV4 TB0 S2 S2");
        w3585("LA STRAIGHT THROUGH, AMPLIFIER IN         ");w3585(lf3585);
        waitfor3585();

        setup_i("K11");
        w3585("RL -15DM SA S2 S2");
        waitfor3585();

        Calpath();
        printf(">>x100 AMP 25 KHz TO 5 MHz %0.3f %0.3f\n",Maxcorr,Maxerror);


//14266    OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"x100 AMP 25 KHz TO 5 MHz",Maxcorr,Maxerror
        Path=5;
        setup_i("-K11");
        w3585("RL -49DM FA 5000000HZ FB 40000000HZ PR RBDN RC4 SV4 TB0 S2 S2");
        w3585("LA STRAIGHT THROUGH, AMPLIFIER IN         ");w3585(lf3585);
        waitfor3585();

        setup_i("K11");
        w3585("RL -15DM SA S2 S2");
        waitfor3585();

        Calpath();
        printf(">>x100 AMP 5 MHz TO 40 MHz %0.3f %0.3f\n",Maxcorr,Maxerror);



//14296    OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"x100 AMP 5 MHz TO 40 MHz",Maxcorr,Maxerror

//  ! CALIBRATE STRAIGHT THROUGH PATH (NO AMP) FROM 25000 TO 40 MHz
        Path=6;
        setup_i("-K1,-K11,-K12");
        w3585("RL -49DM FA 25000HZ FB 40000000HZ PR RBDN RC4 SV4 TB0 S2 S2");
        w3585("LA STRAIGHT THROUGH, AMPLIFIER OUT        ");w3585(lf3585);
        waitfor3585();

        setup_i("K1,K12");
        w3585("SA S2 S2");
        waitfor3585();

        Calpath();
        printf(">>STRAIGHT 25 KHz TO 40 MHz %0.3f %0.3f\n",Maxcorr,Maxerror);


        setup_i("-K1,-K12");
//14332    OUTPUT Printer USING "25A,7X,DD.DDD,14X,DD.DDD";"STRAIGHT 25 KHz TO 40 MHz",Maxcorr,Maxerror
//14338    BEEP
//14341    IF Look=0 THEN GOTO No_output
//14344    OUTPUT Printer USING "//,K,K";".02 TO 40 Hz AMPLIFIER CORRECTION WILL BE:",C(2,1)+C(2,2)*40+C(2,3)*1600+C(2,4)*40^3+C(2,5)/40
//14347    OUTPUT Printer USING "//,5(K,3X)";"INSERTION LOSS COEFFECIENTS:",C(7,1),C(7,2),C(7,3),C(7,4),C(7,5)
//14350 ! OUTPUT Printer USING "///";
//14353 No_output:!
//14356    IF (Printer<>0) AND (Doplot=1) THEN DUMP GRAPHICS

        printf(">> 0.02 TO 40 Hz AMPLIFIER CORRECTION WILL BE: %0.5f\n",Caldata[2][1]+Caldata[2][2]*40+Caldata[2][3]*1600+Caldata[2][4]*40*40*40+Caldata[2][5]/40);
        printf("\nINSERTION LOSS COEFFICIENTS:\n%0.4e %0.4e %0.4e %0.4e %0.4e\n",Caldata[7][1],Caldata[7][2],Caldata[7][3],Caldata[7][4],Caldata[7][5]);


        zerolatch();
        setup_i("F0");

         if ((Overallmaxerror>1.0) | (Overallmaxcorr>=3.5))
         {
             printf("!! Error REF 317; UNABLE TO CALIBRATE 35601A\n");
         } else
         {
             printf("\n35601A calibration complete!\n\n");
         }



}

/*
16858    ! *  NAME: Phioff
16864    ! *  FUNCTION: Calculate the correction factors for a particular
16867    ! *            segment of data.
16873    ! *  INPUT:   Plotindex, Vcoindex, Amplifier,
16876    ! *           Mixerfreq, Caldata(*), W1, W2, W3, Loopbw1, Phaseslope,
16879    ! *           Vcoslope, Vcofreq
16885    ! *  OUTPUT:  Plotdata(*)
*/
// note: Caldata needs to contain current cal data to be used (not necessarily the C cal data determined by Cal!
void Phioff(int Plotdata[][1012], int Plotindex,int Vcoindex,int Measuretype,int Amplifier,double Mixerfreq,double W1,double W2,double W3,double Loopbw1,double Phaseslope,double Vcoslope,double Vcofreq)
{
    double Ang;    //                    !Phase angle of loop correction
    double Bwcorr;    //                 !Bandwidth correction
    double C1,C2,C3,C4,C5;    //         !Signal path correction coeffecients
    int Calnum;    //              !Index into Caldata(*) for coeffecients
    double Corr;    //                   !Correction- bwcorr,phaseslope or vcoslope & gain
    int Cutoff;    //              !Index beyond which loop corrections=0
    double F;    //                      !Freq in Hz
    double Fw;    //                     !F(w), loop correction factor
    int Gain;    //                !Gain from low noise amp
    double Hzpbin;    //                 !Number of Hz per data point
    int I;    //                   !For-next loop counter
    int Maxi;    //                !Max number of points to calibrate
    double Pole;    //
    double R;    //                      !Magnitude of loop correction
    double Rc2pi;    //                  !(R*C*2PI)^2 used in AC COUPLER correction
    double W;    //                      !Freq in radians/sec
    double W5;    //                     !Lead freq in lead-lag
    double Wloopbw1;    //               !Loop bandwidth
    double Ww;    //                     !W  squared
    double Ww1;    //                    !W1 squared
    double Ww2;    //                    !W2 squared
    double Ww3;    //                    !W3 squared
    double Ww5;    //

    int Phioffdone;

    printf("Calculating Phi offset...\n");

//      ! Measuretype 0 -- vco control
//      !   Vcoslope#0  Phaseslope#0   Loopbw1#0  Loopbw3#0
//      !
//      ! Measuretype 1 -- no vco control
//      !   Vcolsope=0  Phaseslope#0   Loopbw1=0  Loopbw3=0
//      !
//      ! Measuretype 2 -- discriminator
//      !   Vcolsope#0  Phaseslope=0   Loopbw1=0  Loopbw3=0

    Phioffdone=0;
    Rc2pi=(1.0E+5*1.0E-5*2.0*M_PI)*(1.0E+5*1.0E-5*2.0*M_PI);

    Plotdata[Plotindex][1007]=2; //valid data flag - corrected data

    if (Plotindex<=10)
    {
        //**3582 Hzpbin=((double)(Plotdata[Plotindex][1010]))/250.0; //these variables are set by getdata

        Hzpbin=((double)(Plotdata[Plotindex][1010]))/800.0; //these variables are set by getdata

        //**3562 Bwcorr=-10.0*log10(363.0/(25000.0/Plotdata[Plotindex][1010]));

        Bwcorr=-10.0*log10(119.0/(25000.0/((double)Plotdata[Plotindex][1010])));//this is for the 3562a

        if (Plotindex<=Vcoindex)
        {
           // AC COUPLER CORRECTION: (HIGH PASS FILTER)
           // HPF : 1/(1+1/RCs)
           // HPF CORRECTION : 1+1/RCs
           // 10*LGT( |1+1/RCs| ^2 )
           // 10*LGT(1+1/(RCW)^2)
           //
           // LAG LEAD : (1+s/W2)/(1+s/W3)
           // 10*LGT( |1+s/W3|^2 / |1+s/W3|^2 )
           // 10*LGT( (1+(W/W2)^2) / (1+(W/W3)^2))
           // where W=(2*PI*F)
           //
           // LEAD: (1+s/W5) -> 10*LGT(|1+s/W5|^2)  -> 10*LGT(1+(W/W5)^2)
           // COMBINING ALL TERMS:
           // 10*LGT( (1+1/(RCW)^2) * (1+(W/W5)^2) * (1+(W/W2)^2) / (1+(W/W3)^2) )
           // RC=100K*10uF =1

            W5=2.0*M_PI*33500.0;
            Ww2=W2*W2;
            Ww3=W3*W3;
            Ww5=W5*W5;

            Corr=10.0*(C1+Bwcorr+20.0*log10(fabs(Vcoslope)));

            //**for (I=1;I<=255;I++)
            for (I=1;I<=800;I++)
            {
                F=I*Hzpbin;
                Ww=2.0*M_PI*2.0*M_PI*F*F;
                Plotdata[Plotindex][I]=(int)(Corr-10.0*20.0*log10(F)+10.0*10.0*log10((1.0+1.0/Ww)*(1.0+Ww/Ww5)*(1.0+Ww/Ww2)/(1.0+Ww/Ww3)));
            }
            printf("Phioff: Plotindex<=VCOindex Correction done, Segment %i!\n",Plotindex);
            Phioffdone=1;
        } else
        {
            Cutoff=(int)(Vcofreq*40/Hzpbin);
            //**3562 Cutoff=(int)FNMin(255,(double)(Cutoff));
            Cutoff=(int)FNMin(800.0,(double)(Cutoff));
            Cutoff=(int)FNMax(0,(double)(Cutoff));
            Gain=40;
            //**3562 Maxi=255;
            Maxi=800;
            printf("Cutoff (LF) %i\n",Cutoff);
        }
    }
      else
    {

        if (Plotindex==11) {Bwcorr=-27.96-0.5;}//    !-.5 IS FOR PEAK DETECT CORRECTION
        if (Plotindex==12) {Bwcorr=-37.96;}   //    !-10*LGT(BW)+2.03857
        if (Plotindex==13) {Bwcorr=-42.73;}  //
        Hzpbin=((double)Plotdata[Plotindex][1010])*10.0;
        Gain=40-6;
        Cutoff=(int)(FNMin(1000.0,Vcofreq*70.0/Hzpbin));
        Cutoff=(int)FNMax((double)(Cutoff),0);
        Maxi=1000;
        printf("Cutoff (HF) %i\n",Cutoff);
    }

    if (!Phioffdone)
    {

//17071 Fwcalc:     !
//      ! CALDATA DEFINITION
//      ! 1) 0-1 MHz     2MHz filter
//      ! 2) 0-400 Hz    amplifier
//      ! 3) 400-25KHz   amplifier
//      ! 4) 25KHz-5MHz  amplifier
//      ! 5) 5KHz-40MHz  amplifier
//      ! 6) 5MHz-40MHz no amplifier
//      ! 7) Insertion loss

    C1=0;
    C2=0;
    C3=0;
    C4=0;
    C5=0;
    if (Amplifier==0) {Gain=0;}

    if (!(Mixerfreq>=9.5E+7))
    {
        C1=Caldata[1][1];//     !2 MHz filter correction
        C2=Caldata[1][2];
        C3=Caldata[1][3];
        C4=Caldata[1][4];//     !NO C5 FOR FILTER
    }

    if (Amplifier!=0)
    {

        if (Plotindex<=4)
        {
            C1=C1+Caldata[2][1]+Caldata[2][2]*40.0+Caldata[2][3]*1600.0+Caldata[2][4]*64000.0+Caldata[2][5]/40.0;
                // ! Calibrate amplifier for freqs < 40 Hz
        }
        else
        {
            if (Plotindex==13) {Calnum=5;}     // Amplifier 5 MHz to 40 MHz
            if (Plotindex==12) {Calnum=4;}     // Amplifier 25 KHz to 5 MHz
            if (Plotindex==11) {Calnum=4;}     // Amplifier 25 KHz to 5 MHz
            //**3582 if (Plotindex<=10) {Calnum=3;}    // Amplifier 400 Hz to 25 KHz
            //**3582 if (Plotindex<=6) {Calnum=2;}     // Amplifier 40 Hz to 400 Hz

            if (Plotindex<=10) {Calnum=3;}    // Amplifier 400 Hz to 25 KHz
            if (Plotindex<=7) {Calnum=2;}     // Amplifier 40 Hz to 400 Hz

            C1=C1+Caldata[Calnum][1];
            C2=C2+Caldata[Calnum][2];
            C3=C3+Caldata[Calnum][3];
            C4=C4+Caldata[Calnum][4];
            C5=C5+Caldata[Calnum][5];
        }

    }

 //  Calibrate insertion loss
    C1=C1+Caldata[7][1]+Caldata[6][1];

    if (!(Plotindex<=10))
    {
        C2=C2+Caldata[7][2]+Caldata[6][2];
        C3=C3+Caldata[7][3]+Caldata[6][3];
        C4=C4+Caldata[7][4]+Caldata[6][4];
        C5=C5+Caldata[7][5]+Caldata[6][5];
    }


// do the actual data correction
    if (Measuretype==0)
    {
        Ww1=W1*W1;
        Ww2=W2*W2;
        Ww3=W3*W3;
        Wloopbw1=2.0*M_PI*Loopbw1;
        Corr=10.0*(Bwcorr-20.0*log10(Phaseslope)-(double)Gain);

        printf("C[I] %e %e %e %e %e\n",C1,C2,C3,C4,C5);
        printf("BWcorr %0.3f\n",Bwcorr);
        printf("Phaseslope corr %0.3f\n",-20.0*log10(Phaseslope));
        printf("Gain corr %0.3f\n",-(double)Gain);
        printf("Corr %0.3f\n",Corr/10);
        printf("Hzpbin %0.3f\n",Hzpbin);
        printf("Plotindex %i\n",Plotindex);
        printf("Hz Stopindex %0.3f\n",Hzpbin*((double)Plotdata[Plotindex][1009]));


        for (I=1; I<=Cutoff; I++)
        {
            F=I*Hzpbin;
            W=2.0*M_PI*F;
            Ww=W*W;
          //  W0=1/2   W0^2=.25
            R=Wloopbw1/W*sqrt((1+Ww/Ww2)*(1.0+0.25/Ww)/((1.0+Ww/Ww3)*(1.0+Ww/Ww1)));
            Pole=W/1.75E+6;
            if (Pole>(M_PI/2.0)) {Pole=M_PI/2.0;}
            Ang=-atan(W/W1)+atan(W/W2)-atan(W/W3)-M_PI/2.0-atan(0.5/W)-Pole;
            Fw=-10.0*log10(1.0+2.0*R*cos(Ang)+R*R);
            F=FNMax(F,Hzpbin*((double)Plotdata[Plotindex][1009])); //stopindex stored in 1009
            Plotdata[Plotindex][I]=(int)(Corr-10.0*Fw+10.0*(C5/F+C1+F*(C2+F*(C3+F*C4))));
            //**3562 needs to be checked
            //if (Plotindex<=2) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+(int)(100.0*log10(1.0+1.0/Ww));}
            if (Plotindex<=3) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+(int)(100.0*log10(1.0+1.0/Ww));}

        }

        for (I=Cutoff+1;I<=Maxi;I++)
        {
            F=I*Hzpbin;
            F=FNMax(F,Hzpbin*(double)(Plotdata[Plotindex][1009]));
            Plotdata[Plotindex][I]=(int)(Corr+10*(C5/F+C1+F*(C2+F*(C3+F*C4))));

            //**3562 needs to be checked; old seg 2 is up to 5 hz
            //if (Plotindex<=2) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+(int)(100.0*log10(1.0+1.0/(Rc2pi*F*F)));}
            if (Plotindex<=3) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+(int)(100.0*log10(1.0+1.0/(Rc2pi*F*F)));}
        }

    }
   else
//Cal no vco
    if (Measuretype==1)
    {
        Corr=10*(Bwcorr-20*log10(Phaseslope)-Gain);
        for (I=1;I<=Maxi;I++)
        {
            F=I*Hzpbin;
            F=FNMax(F,Hzpbin*(Plotdata[Plotindex][1009]));
            Plotdata[Plotindex][I]=Corr+10.0*(C5/F+C1+F*(C2+F*(C3+F*C4)));
            if (Plotindex<=2) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+100.0*log10(1.0+1.0/(Rc2pi*F*F));}
        }
    }
   else
//Cal discrim
    if (Measuretype==2)
    {

     //  VCOSLOPE IS THE RECIPROCAL OF THE DISCRIMINATOR CONSTANT
     //  S PHI(F)=V^2 * (Hz/V)^2 / F^2  = S NU / F^2

        Corr=10.0*(Bwcorr+20.0*log10(Vcoslope)-Gain);
        for (I=1;I<=Maxi;I++)
        {
            F=I*Hzpbin;
            F=FNMax(F,Hzpbin*(Plotdata[Plotindex][1009]));
            Plotdata[Plotindex][I]=Corr+10.0*(-20.0*log10((double)I*Hzpbin)+C5/F+C1+F*(C2+F*(C3+F*C4)));
            if (Plotindex<=2) {Plotdata[Plotindex][I]=Plotdata[Plotindex][I]+100.0*log10(1.0+1.0/(Rc2pi*F*F));}
        }
    }
   else
    {
        printf("!! Error: Unknown measurement type: %d\n",Measuretype);
    }

   }
}


#define C_Phaseslope 0
#define C_Gain1 1
#define C_Gain2 2
#define C_Atten1 3
#define C_Atten2 4
#define C_Vcoslope 5
#define C_Vpeak 6
#define C_DAC 7


void writef_cal(char fname[100])
{
    calparameters[C_Phaseslope]=Phaseslope;
    calparameters[C_Vcoslope]=Vcoslope;
    calparameters[C_Vpeak]=Vpeak;

    FILE *f = fopen(fname, "wb");
    printf("Storing cal data in file %s ...",fname);
    fwrite(caltexts, sizeof(char), sizeof(caltexts), f);
    fwrite(calparameters, sizeof(char), sizeof(calparameters), f);
    fwrite(Caldata, sizeof(char), sizeof(Caldata), f);
    fclose(f);
    printf(" Done.\n");
}

void readf_cal(char fname[100])
{
    FILE *f = fopen(fname, "r");
    printf("Reading cal data from file %s ...",fname);
    fread(caltexts, sizeof(char), sizeof(caltexts), f);
    fread(calparameters, sizeof(char), sizeof(calparameters), f);
    fread(Caldata, sizeof(char), sizeof(Caldata), f);
    fclose(f);
    printf(" Done.\n");

    Phaseslope=calparameters[C_Phaseslope];
    Vcoslope=calparameters[C_Vcoslope];
    Vpeak=calparameters[C_Vpeak];

    printf("VCOSLOPE=%e Hz/V\n",Vcoslope/Atten1);
    printf("PHASESLOPE=%e V/rad\n",Phaseslope);
    printf("VPEAK=%0.2f V\n",Vpeak);


}


void writef_trace(char fname[100])
{
    FILE *f = fopen(fname, "wb");
    printf("Storing trace data in file %s ...",fname);
    fwrite(tracetexts, sizeof(char), sizeof(tracetexts), f);
    fwrite(traceparameters, sizeof(char), sizeof(traceparameters), f);
    fwrite(tracedata, sizeof(char), sizeof(tracedata), f);
    fclose(f);
    printf(" Done.\n");
}

void writef_tracetxt(char fname[100])
{
    int I,J;
    int startbin,stopbin;
    double hzpbin;
    double freq;

    FILE *f = fopen(fname, "wb");
    printf("Storing trace data (text) in file %s ...",fname);

    //fwrite(traceparameters, sizeof(char), sizeof(traceparameters), f);
    //fwrite(traceparameters, sizeof(char), sizeof(traceparameters), f);
    fprintf(f,"PHASE NOISE TRACE DATA\n");
    for (I=1;I<=13;I++)
    {
        if (tracedata[I][1007]>0.1) //valid segment
        {

            if (I>=11)
            {
                startbin=P85[I][1008];
                stopbin=P85[I][1009];
                hzpbin=(double)P85[I][1010];
            } else
            {
                startbin=P82[I][1008];
                stopbin=P82[I][1009];
                hzpbin=(double)P82[I][1010];
            }


            if (I>10) {hzpbin=hzpbin*10;} else
                //{hzpbin=hzpbin/250;}
                {hzpbin=hzpbin/800.0;}

            //fprintf(f,"SEG %i\n",I);
            //printf("%i %i %i\n",I,startbin,stopbin);
            //printf("%i %i %i\n",I,P85[I][0],P85[I][1]);

            for (J=startbin;J<=stopbin;J++)
            {
                freq=hzpbin*(double)J;
             //   fprintf(f,"TRA: %i: %0.3f Hz, %0.2f dBc\n",J-startbin,freq,tracedata[I][J]);
              if (I>=11)
              {
                fprintf(f,"%i %i %0.2f %0.1f %0.1f %0.1f\n",I,J-startbin,freq,tracedata[I][J],0.1*(double)P85_C[I][J],tracedata[I][J]+0.1*(double)P85_C[I][J]);
              } else
              {
                 fprintf(f,"%i %i %0.2f %0.1f %0.1f %0.1f\n",I,J-startbin,freq,tracedata[I][J],0.1*(double)P82_C[I][J],tracedata[I][J]+0.1*(double)P82_C[I][J]);
              }

            }
        }
    }
    //fwrite(tracedata, sizeof(char), sizeof(tracedata), f);
    fprintf(f,"EOF\n");
    fclose(f);
    printf(" Done.\n");
}

int Measuretype_t, Caltype_t;

void do_trace_corr()  //calculated trace data from valid P82, P85 data
{
   int I,J;

//for the 3562a data
   for (I=3;I<=10;I++)  //segment 3 is lowest segment fo 3562a
   {
       if (P82[I][1007]==1)
       {
            P82_C[I][1008]=P82[I][1008];
            P82_C[I][1009]=P82[I][1009];
            P82_C[I][1010]=P82[I][1010];
            printf("Correction... LF Segment %i\n",I);
            Phioff(P82_C,I,Vcoindex,Measuretype_t,Amplifier,Mixer,W1,W2,W3,Loopbw1,Phaseslope,Vcoslope,Vcofreq);
       }
   }

   for (I=3;I<=10;I++)
   {
       if (P82[I][1007]==1) //valid data
       {
           for(J=0;J<=800;J++)
           {
                tracedata[I][J]=((double)P82[I][J])/10.0;
           }
           tracedata[I][1007]=1.0; //valid data
       }

   }


   //Phioff(int Plotdata[][1012], int Plotindex,int Vcoindex,int Measuretype,int Amplifier,double Mixerfreq,double W1,double W2,double W3,double Loopbw1,double Phaseslope,double Vcoslope,double Vcofreq)
   for (I=11;I<=13;I++)
   {
       if (P85[I][1007]==1)
       {
            P85_C[I][1008]=P85[I][1008];
            P85_C[I][1009]=P85[I][1009];
            P85_C[I][1010]=P85[I][1010];
            printf("Correction... HF Segment %i\n",I);
            Phioff(P85_C,I,Vcoindex,Measuretype_t,Amplifier,Mixer,W1,W2,W3,Loopbw1,Phaseslope,Vcoslope,Vcofreq);
       }
   }

   for (I=11;I<=13;I++)
   {
       if (P85[I][1007]==1) //valid data
       {
           for(J=0;J<=1000;J++)
           {
                tracedata[I][J]=((double)P85[I][J])/10.0;
           }
           tracedata[I][1007]=1.0; //valid data
       }

   }


}




void main() {



   char *commandset=(char *) malloc (255);   //command string separated by komma
   //char *token=(char *) malloc (255);
   //char *cp=(char *) malloc (255);
   unsigned long LocalIbsta;
   char SpollByte;

   time_t t;
   int i,j;

   /* Intializes random number generator */
   srand((unsigned) time(&t));

   //for (i=0;i<1000;i++) {printf("%0.5f ",frand());}


   //writef_trace("c:\\werkstatt\\pn\\testtrace.bnoise");

   //tracedata[11][1007]=1;
   //tracedata[12][1007]=1;
   //tracedata[13][1007]=1;

   //writef_tracetxt("c:\\werkstatt\\pn\\testtrace.pdat");



/*****************************************************************************
 * Initialization - Done only once at the beginning of your application.
 *****************************************************************************/

   Device35601 = ibdev(                /* Create a unit descriptor handle         */
         BoardIndex,              /* Board Index (GPIB0 = 0, GPIB1 = 1, ...) */
         PrimaryAddress35601,          /* Device primary address                  */
         SecondaryAddress35601,        /* Device secondary address                */
         T10s,                    /* Timeout setting (T10s = 10 seconds)     */
         1,                       /* Assert EOI line at end of write         */
         0);                      /* EOS termination mode                    */
   if (Ibsta() & ERR) {           /* Check for GPIB Error                    */
      GpibError("ibdev Error");
   }

   ibclr(Device35601);                 /* Clear the device                        */
   if (Ibsta() & ERR) {
      GpibError("ibclr Error");
   }

   Device3585 = ibdev(                /* Create a unit descriptor handle         */
         BoardIndex,              /* Board Index (GPIB0 = 0, GPIB1 = 1, ...) */
         PrimaryAddress3585,          /* Device primary address                  */
         SecondaryAddress3585,        /* Device secondary address                */
         T10s,                    /* Timeout setting (T10s = 10 seconds)     */
         1,                       /* Assert EOI line at end of write         */
         0);                      /* EOS termination mode                    */

   if (Ibsta() & ERR) {           /* Check for GPIB Error                    */
      GpibError("ibdev Error");
   }
   ibclr(Device3585);                 /* Clear the device                        */
   if (Ibsta() & ERR) {
      GpibError("ibclr Error");
   }


    Device3562 = ibdev(                /* Create a unit descriptor handle         */
         BoardIndex,              /* Board Index (GPIB0 = 0, GPIB1 = 1, ...) */
         PrimaryAddress3562,          /* Device primary address                  */
         SecondaryAddress3562,        /* Device secondary address                */
         T10s,                    /* Timeout setting (T10s = 10 seconds)     */
         1,                       /* Assert EOI line at end of write         */
         0);                      /* EOS termination mode                    */

   if (Ibsta() & ERR) {           /* Check for GPIB Error                    */
      GpibError("ibdev Error");
   }
   ibclr(Device3562);                 /* Clear the device                        */
   if (Ibsta() & ERR) {
      GpibError("ibclr Error");
   }



 //   i3562_timeb_init();


/*
   range_3562=7;

   i3562_pwrspec_init();

   i3562_pwrspec(10,range_3562,4);

   i3562_pwrspec(10,range_3562,4);
*/

 //  getchar();
 //  exit(1);

   //i3562_timeb();



   toggle_i(NOCOMMAND); //make sure the GPIB is working with 35601a interface
   toggle_i(OVERLOAD);

   // commandset= "-K6,-K7,-K1,-K13,K8,K9,-K11,K12,K10,S3,-S4";

 //  commandset= "-K1,-K13,K8,K9,K11,K12,K10,S3,-S4"; //40 db gain

   //commandset= "K6,K7,S2,-K1,-K13,K8,K9,-K11,K12,K10,S3,-S4"; //tracking gen

  // commandset= "-K6,-K7,-K1,-K13,K8,K9,-K11,K12,-K10,-S1,-S2,-S3,-S4";//loop open



   //printf("%f\n",DROUND(22423432.3434234,9));


   //Cal();

   //printf("PRESS ANY KEY!\n");
   //getchar();



   zerolatch();


/*    setup_i("K1,K8,K9,K11,S7,L1,L3,L5,L8,L9,K12,-K10,-S3,-S4");

    setup_i("F1");
    toggle_i(TOGGLEACDC);
    getchar();
    setup_i("F2");
    toggle_i(TOGGLEACDC);
    getchar();
    setup_i("F0");
    toggle_i(TOGGLEACDC);
    getchar();



    getchar();
exit(1);

*/
   Gain1=6.0;
   Gain2=6.0;
   Amplifier=0;



   getuserparms();

  //readf_cal("c:\\werkstatt\\pn\\testcal.cal"); //need to watch out for atten1 values etc


   value_i(DAC,0.00);//0.1
   value_i(GAIN1,Gain1);//6
   value_i(GAIN2,Gain2);//20
   value_i(LEADLAG,0);//2
   value_i(ATTEN1,Atten1db);//0
   value_i(ATTEN2,Atten2db);//0

   setup_i("K12,K10,S3,S8,L1,L3,L5,L8,L9,S4"); //close loop


/*
//follows: test for small bw loop char
   setup_i("K8,K9"); //low pass

   setup_i("K12,K10,S3,S8,L1,L3,L5,L8,L9,S4"); //close loop

   setup_i("-K6,-K7,K12,K10,-S1,-S2,S3,S4");//loop closed
   setup_i("L2,K10,S3");

//    IF Loopbw3<=20 THEN CALL Setupinterface("L0,-L9,S1,S5,-K7,-K6,-S2")

   setup_i("L0,-L9,S1,S5,-K7,-K6,-S2");

   toggle_i(NOCOMMAND); //make sure the GPIB is working with 35601a interface
   toggle_i(OVERLOAD);
   toggle_i(OUTOFLOCK);

   //setup_i("L0,-L9"); //noise to 3562A a input

   //setup_i("S1,S5"); //noise to 3562A summing jnctn

   toggle_i(TOGGLEACDC);

   i3562_charloop_init(200,4);
   i3562_charloop(200,4);
   i3562_get8db();

   getchar();

   setup_i("-S1,-L0,L9"); //noise to 3562A a input





printf("...\n\n");
getchar();
exit(1);
*/
   Measuretype_t=0; //phase noise measurement
   Caltype_t=2; //beatnote measurement of constant

   setup_i("L1,L3,L5,L8,L9,K12,-K10,-S3,-S4"); //loop is open


   if (Mixerfreq<9.5E+7) {setup_i("K8,K9"); printf("2 MHz LPF is IN\n");}      // ! 2MHz LPF
   if (Mixerfreq>=9.5E+7) {setup_i("-K8,-K9"); printf("2 MHz LPF is OUT\n");}   //LFP out

   if (Mixer==1) {setup_i("-K13");}
   if (Mixer==2) {setup_i("K13");}
   if (Mixer<3) {setup_i("-K1");} //internal mixers
   if (Mixer==3) {setup_i("K1");} //External mixer

   print_i_setup();



   //printf("%f\n",FNPround(21172.213143213,-4));


   readf_cal("c:\\werkstatt\\pn\\testcal.cal");

   Approxfreq=28800e3;

   autorange85();



  getvcoslope();

  Getphaseslope(Vbeatnote,Fbeatnote,Measuretype_t,Caltype_t);

  // writef_cal("c:\\werkstatt\\pn\\testcal.cal");


 // readf_cal("c:\\werkstatt\\pn\\testcal.cal");

 //  printf("Press key...\n");
 //  getchar();



   Charloop();

  // printf("Press key to start PN measurement...\n");
  // getchar();

   printf("Setting up for PN measurement...\n");
 //  print_i_setup();

   zerolatch();

   setup_i("K12,K10,S3,S8,L1,L3,L5,L8,L9,S4"); //close loop

   value_i(DAC,Lockvoltage);//0.1

   value_i(GAIN1,Gain1);//6
   value_i(GAIN2,Gain2);//20


   value_i(LEADLAG,Laglead);//2
   value_i(ATTEN1,Atten1db);//0
   value_i(ATTEN2,Atten2db);//0
 //  print_i_setup();

 //  printf("lead and atten is set...\n");
 //  getchar();




   setup_i("K12,K10,S3,S8,L1,L3,L5,L8,L9,S4"); //close loop

   //printf("close sent\n");
   //printf("Ampl %i\n",Amplifier);
   //getchar();

   Amplifier=1;
   Vcoport=0;

   if (Amplifier==1) {setup_i("K11");} else  {setup_i("-K11");}
   if (Amplifier==0) { setup_i("S8");}
   if (Amplifier==1) { setup_i("S7");} //route the correct signal to the LF board

   if (Mixerfreq<9.5E+7) {setup_i("K8,K9"); printf("2 MHz LPF is IN\n");}      // ! 2MHz LPF
   if (Mixerfreq>=9.5E+7) {setup_i("-K8,-K9"); printf("2 MHz LPF is OUT\n");}   //LFP out

   if (Mixer==1) {setup_i("-K13");}
   if (Mixer==2) {setup_i("K13");}
   if (Mixer<3) {setup_i("-K1");} //internal mixers
   if (Mixer==3) {setup_i("K1");} //External mixer


   //value_i(DAC,Lockvoltage);//set DAC for lock voltage
  // printf("DAC set at: %0.3f Volt\n",Lockvoltage);
 //  print_i_setup();

   commandset= "-K6,-K7,K12,K10,-S1,-S2,S3,S4";//loop closed

   setup_i(commandset);
   wait_s01(20);
   toggle_i(OUTOFLOCK);

   printf("Press key to start PN measurement...\n");
   getchar();

   printf("PN measurement started:\n");

   printf("Running getdata...\n");

      //** need to add autorange after each filter change
   range_3562=7;

   i3562_pwrspec_init();


   getdata();


   setup_i("F0");  //seg 3: F2; seg 4-6 F1, seg 7- F0;
   toggle_i(TOGGLEACDC);
   i3562_pwrspec(10,range_3562,30);
   i3562_pwrspec(10,range_3562,30);

   i3562_pwrspec(9,range_3562,30);

   setup_i("S5");
   Vcoport=1;

   i3562_pwrspec(8,range_3562,30);

   i3562_pwrspec(7,range_3562,30);

   setup_i("F1");  //seg 3: F2; seg 4-6 F1, seg 7- F0;
   toggle_i(TOGGLEACDC);

   i3562_pwrspec(6,range_3562,5); //5

   i3562_pwrspec(5,range_3562,4); //4

   i3562_pwrspec(4,range_3562,3); //3

   setup_i("F2");  //seg 3: F2; seg 4-6 F1, seg 7- F0;
   toggle_i(TOGGLEACDC);

  // i3562_pwrspec(3,range_3562,3); //3


   setup_i("F0");  //seg 3: F2; seg 4-6 F1, seg 7- F0;
   toggle_i(TOGGLEACDC);


   do_trace_corr();


   writef_tracetxt("c:\\werkstatt\\pn\\testvco10.pnd");


/*****************************************************************************
 * Uninitialization - Done only once at the end of your application.
 *****************************************************************************/

   ibonl(Device35601, 0);              /* Take the device offline                 */
   if (Ibsta() & ERR) {
      GpibError("ibonl Error");
   }

   ibonl(Device3585, 0);              /* Take the device offline                 */
   if (Ibsta() & ERR) {
      GpibError("ibonl Error");
   }

   exit(0);

}


/*****************************************************************************
 *                      Function GPIBERROR
 * This function will notify you that a NI-488 function failed by
 * printing an error message.  The status variable IBSTA will also be
 * printed in hexadecimal along with the mnemonic meaning of the bit
 * position. The status variable IBERR will be printed in decimal
 * along with the mnemonic meaning of the decimal value.  The status
 * variable IBCNT will be printed in decimal.
 *
 * The NI-488 function IBONL is called to disable the hardware and
 * software.
 *
 * The EXIT function will terminate this program.
 *****************************************************************************/
void GpibError(const char *msg) {

    printf("%s\n", msg);

    printf("Ibsta() = 0x%x  <", Ibsta());
    if (Ibsta() & ERR )  printf(" ERR");
    if (Ibsta() & TIMO)  printf(" TIMO");
    if (Ibsta() & END )  printf(" END");
    if (Ibsta() & SRQI)  printf(" SRQI");
    if (Ibsta() & RQS )  printf(" RQS");
    if (Ibsta() & CMPL)  printf(" CMPL");
    if (Ibsta() & LOK )  printf(" LOK");
    if (Ibsta() & REM )  printf(" REM");
    if (Ibsta() & CIC )  printf(" CIC");
    if (Ibsta() & ATN )  printf(" ATN");
    if (Ibsta() & TACS)  printf(" TACS");
    if (Ibsta() & LACS)  printf(" LACS");
    if (Ibsta() & DTAS)  printf(" DTAS");
    if (Ibsta() & DCAS)  printf(" DCAS");
    printf (" >\n");

    printf ("Iberr() = %d", Iberr());
    if (Iberr() == EDVR) printf(" EDVR <Driver error>\n");
    if (Iberr() == ECIC) printf(" ECIC <Not Controller-In-Charge>\n");
    if (Iberr() == ENOL) printf(" ENOL <No Listener>\n");
    if (Iberr() == EADR) printf(" EADR <Address error>\n");
    if (Iberr() == EARG) printf(" EARG <Invalid argument>\n");
    if (Iberr() == ESAC) printf(" ESAC <Not System Controller>\n");
    if (Iberr() == EABO) printf(" EABO <Operation aborted>\n");
    if (Iberr() == ENEB) printf(" ENEB <No GPIB board>\n");
    if (Iberr() == EOIP) printf(" EOIP <Async I/O in progress>\n");
    if (Iberr() == ECAP) printf(" ECAP <No capability>\n");
    if (Iberr() == EFSO) printf(" EFSO <File system error>\n");
    if (Iberr() == EBUS) printf(" EBUS <Command error>\n");
    if (Iberr() == ESTB) printf(" ESTB <Status byte lost>\n");
    if (Iberr() == ESRQ) printf(" ESRQ <SRQ stuck on>\n");
    if (Iberr() == ETAB) printf(" ETAB <Table Overflow>\n");
    if (Iberr() == ELCK) printf(" ELCK <Lock error>\n");
    if (Iberr() == EARM) printf(" EARM <Ibnotify rearm error>\n");
    if (Iberr() == EHDL) printf(" EHDL <Invalid Handle>\n");
    if (Iberr() == EWIP) printf(" EWIP <Wait already in progress>\n");
    if (Iberr() == ERST) printf(" ERST <Notification cancelled due to reset>\n");
    if (Iberr() == EPWR) printf(" EPWR <Power error>\n");

    printf("Ibcnt() = %u\n", Ibcnt());
    printf("\n");

    /* Call ibonl to take the device and interface offline */
    //ibonl(Device, 0);

    exit(1);
}
