/* Output from p2c, the Pascal-to-C translator */
/* From input file "k196_con.text" */




#include <p2c/p2c.h>


#define K196_CON_G
#include "k196_con.h"


#ifndef IODECLARATIONS_H
#include <p2c/iodecl.h>
#endif

#ifndef GENERAL_0_H
#include <p2c/general_0.h>
#endif

#ifndef GENERAL_2_H
#include <p2c/general_2.h>
#endif

#ifndef GENERAL_1_H
#include <p2c/general_1.h>
#endif

#ifndef SYSDEVS_H
#include <p2c/sysdevs.h>
#endif

#ifndef HPIB_1_H
#include <p2c/hpib_1.h>
#endif

#ifndef HPIB_2_H
#include <p2c/hpib_2.h>
#endif

#ifndef HPIB_3_H
#include <p2c/hpib_3.h>
#endif

#ifndef HPIB_0_H
#include <p2c/hpib_0.h>
#endif

#ifndef NEWASM_H
#include <p2c/newasm.h>
#endif

#ifndef SYSGLOBALS_H
#include <p2c/sysglobals.h>
#endif


#define k196Addr        707


Static long waitsecs, waitread, waitset;


Static Void Wait(sec)
double sec;
{
  /*wait for sec seconds*/
  long t;

  t = sysclock();
  while (t + sec * 100 > sysclock()) ;
}


Static boolean Ready()
{
  /*Performs a Serial Poll of the Keithley 196
    and waits until it gets a ready bit set.*/
  long status;
  boolean done;

  done = false;
  do {
    status = P_spoll((long)k196Addr);   /*read serial pole byte*/
    if ((status & (1L << 4)) != 0)
      done = true;
  } while (!done);
  return true;
}  /*ready*/


Static boolean Readingdone()
{
  /*Performs a Serial Poll of the Keithley 196
    and waits until it gets a reading done bit set.*/
  long status, i;
  boolean done;

  done = false;
  i = 0;
  do {
    status = P_spoll((long)k196Addr);   /*read serial pole byte*/
    if ((status & (1L << 3)) != 0)
      done = true;
    i++;
    /*    if i >= 500 then
          begin
            writeln('Timeout Error in Keithley 196, Reading cycle not ending');
            done:=true;
          end;           */
  } while (!done);
  return true;
}  /*readingdone*/


boolean K196_Error()
{
  /*  Performs an error check of the Keithley 196.

      Returns : TRUE if error condition exists.
                FALSE otherwise
  */
  boolean Result;
  Char ErrStr[256];
  long status;

  Result = false;
  status = P_spoll((long)k196Addr);
  if ((status & (1L << 5)) == 0)
    return Result;
  Result = true;
  if (Ready())
    P_writestringln((long)k196Addr, "G1U1X");
  if (Ready())
    P_readstring((long)k196Addr, ErrStr);
  printf("Error String= %s\n", ErrStr);
  if (ErrStr[0] == '1')
    printf("Trigger Error\n");
  if (ErrStr[11] == '1')
    printf("Illegal Command Option\n");
  if (ErrStr[12] == '1')
    printf("Illegal Command\n");
  if (ErrStr[10] == '1')
    printf("No Remote\n");
  return Result;
}  /*K196_Error*/


Void trigger_K196()
{
  /*triggers the Keithley 196 */
  if (Ready())   /*trigger Keithley 196*/
    P_writestringln((long)k196Addr, "T5X");
}  /*trigger_k196*/



Void Init_K196()
{
  /*Auto,Disable SRQ,Trigger on X,No prefix,4 1/2 digits,(Trigger)*/
  if (Ready())
    P_writestringln((long)k196Addr, "R0M0T5G1S1X");
  if (K196_Error())
    printf("Error occurred initializing Keithley 196\n");
}  /*Init_K196*/


Void Set_k196_Res(res)
long res;
{
  /* Sets the resolution of the 196

     3 = 3 1/2 digits - S0
     4 = 4 1/2 digits - S1
     5 = 5 1/2 digits - S2
     6 = 6 1/2 digits - S3  */
  Char Cmd_Str[256];
  long Length, j;

  if ((unsigned long)res >= 32 || ((1L << res) & 0x78) == 0) {
    printf("ILLEGAL resolution for K196 :  %ld\n", res);
    return;
  }
  strcpy(Cmd_Str, " ");
  waitsecs = 0;
  switch (res) {

  case 3:
    j = 0;
    break;

  case 4:
    j = 1;
    break;

  case 5:
    j = 2;
    break;

  case 6:
    j = 3;
    waitsecs = 4;
    /*with 6 1/2 digit resolution
                    the 196 takes 3 secs. for 1 reading*/
    break;
  }/*case*/

  sprintf(Cmd_Str, "S%ldX", j);
  Length = strlen(Cmd_Str) + 1;
  if (Ready())
    P_writestringln((long)k196Addr, Cmd_Str);
  if (K196_Error())
    printf("Error occurred in Set_196_Res, with Cmd_Str=%s\n", Cmd_Str);
}


Void Set_k196_Range(range)
long range;
{

  /*Sets the 196 range to  Auto if 0 or to the range selected by
    the integer 1 thru 7*/
  Char Cmd_Str[256];
  long Length;

  if ((unsigned long)range >= 32 || ((1L << range) & 0xff) == 0) {
    printf("ILLEGAL range for K196 :  %ld\n", range);
    return;
  }
  strcpy(Cmd_Str, " ");
  sprintf(Cmd_Str, "R%ldX", range);
  Length = strlen(Cmd_Str) + 1;
  if (Ready())
    P_writestringln((long)k196Addr, Cmd_Str);
  Wait((double)waitset);
  if (K196_Error())
    printf("Error occurred in Set_196_Range, with Cmd_Str=%s\n", Cmd_Str);
}


Void Set_k196_Mode(M, T)
Char M, T;
{

  /*  Determines the mode of operation of the
      Keithley 196 System DMM

      "M"
         'V'  ==>  Voltmeter
         'A'  ==>  Ammeter
         'R'  ==>  Ohmmeter

      "T"
         'A'  ==>  AC
         'D'  ==>  DC
         'B'  ==>  dB
  */
  Char Cmd_Str[256];
  long Length, j;

  M = toupper(M);   /* Change lower case letters to upper case */
  T = toupper(T);
  if (M != 'R' && M != 'A' && M != 'V' && T != 'B' && T != 'D' && T != 'A') {
    printf("ILLEGAL mode for K196 :  %c%c\n", T, M);
    return;
  }
  waitread = 0;
  if (M == 'V' && T == 'D')
    j = 0;
  else {
    if (M == 'V' && T == 'A') {
      j = 1;
      waitread = 1;
    } else {
      if (M == 'R')
	j = 2;
      else {
	if (M == 'A' && T == 'D')
	  j = 3;
	else {
	  if (M == 'A' && T == 'A')
	    j = 4;
	  else {
	    if (M == 'V' && T == 'B')
	      j = 5;
	    else {
	      if (M == 'A' && T == 'B')
		j = 6;
	    }
	  }
	}
      }
    }
  }
  strcpy(Cmd_Str, " ");
  sprintf(Cmd_Str, "F%ldX", j);
  Length = strlen(Cmd_Str) + 1;
  if (Ready())
    P_writestringln((long)k196Addr, Cmd_Str);
  Wait((double)waitset);
  if (K196_Error())
    printf("Error occurred in Set_k196_Mode, with Cmd_Str=%s\n", Cmd_Str);
}  /*Set_k196_Mode*/


Void Set_k196_Filter(filter)
long filter;
{

  /*Sets filter function to off if filter = 0
    Number of readings averaged if filter = 1-99*/
  Char Cmd_Str[256];
  long Length;

  if ((unsigned long)filter > 99) {
    printf("Illegal number of readings to be averaged in Set_k196_filter(1-99)\n");
    return;
  }
  strcpy(Cmd_Str, " ");
  if (filter == 0) {
    if (Ready())
      P_writestringln((long)k196Addr, "P0X");
  } else {
    if ((unsigned long)filter < 32 && ((1L << filter) & 0x3fe) != 0) {
      sprintf(Cmd_Str, "P%d%ldX", 0, filter);
      Length = strlen(Cmd_Str) + 1;
    } else if (filter >= 10 && filter <= 99) {
      sprintf(Cmd_Str, "P%2ldX", filter);
      Length = strlen(Cmd_Str) + 1;
    }
    if (Ready())
      P_writestringln((long)k196Addr, Cmd_Str);
  }
  if (K196_Error())
    printf("Error occurred in Set_k196_Filter, with Cmd_Str=%s\n", Cmd_Str);

}  /*Set_k196_filter*/


double Read_k196()
{
  /*  Reads Keithley 196 DVM  */
  double Result;
  Char Answer[256];
  long Length;
  double Dummy;
  Char *STR2;

  Wait((double)waitread);   /*wait for meter to settle after input change*/
  Wait((double)waitsecs);
      /*wait for meter to get data accurately with resolution*/
  if (Ready())   /*Start a new set of data reading*/
    trigger_K196();
  if (Readingdone()) {   /*send prefix back with data ,trigger*/
    if (Ready())
      P_writestringln((long)k196Addr, "G0X");
  }
  P_readstring((long)k196Addr, Answer);
  if (K196_Error()) {
    printf("Error occurred in Read_k196\n");
    return 0.0;
  }

  Dummy = strtod(Answer + 4, &STR2);
  Length = STR2 - Answer + 1;
  Result = Dummy;   /*Place to hold data*/
  if (Answer[0] == 'O')
    printf("*** K196 OVERFLOW ***\n");
  return Result;

  /*no error*/
}  /*Read_k196*/


Void Reset_k196()
{
  /*put 196 into continous trigger and local mode*/
  if (Ready())
    P_writestringln((long)k196Addr, "T4X");
  P_clear((long)k196Addr);
  P_local((long)k196Addr);
  if (cleariohook.link != NULL)
    (*(Void(*) PP((Anyptr _link)))cleariohook.proc)(cleariohook.link);
  else
    (*(Void(*) PV())cleariohook.proc)();
}






/* End. */
