home *** CD-ROM | disk | FTP | other *** search
/ Chip 1997 September / CHIP_CD_1997_09_PL.iso / software / testsoft / labwind / demo.6 / main / instr / hp34401a.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-08-02  |  60.2 KB  |  1,266 lines

  1. /*****************************************************************************/
  2. /*   Copyright 1996 National Instruments Corporation.  All Rights Reserved.  */
  3. /*****************************************************************************/
  4.  
  5. #include <formatio.h>
  6.  
  7.  
  8. #include <visa.h>
  9. #include <ansi_c.h>
  10. #include "hp34401a.h"
  11.  
  12. #define hp34401a_REVISION     "Rev 1.0b, 9/95, CVI 3.1" /*  Instrument driver revision */
  13. #define BUFFER_SIZE     256L         /* File I/O buffer size */
  14. #define MAX_CMD_LENGTH  256L
  15.     
  16. /* = Hewlett-Packard 34401A Multimeter (VISA) ============================== */
  17. /*  LabWindows 3.1 Instrument Driver                                         */
  18. /*  Original Release: October, 1992                                          */
  19. /*  By: HG, LWILDP, National Instruments, Austin, TX                         */
  20. /*     PH. (800)433-3488   Fax (512)794-5678                                 */
  21. /*  Originally written in C                                                  */
  22. /*  Modification History:                                                    */
  23. /*                                                                           */
  24. /*      June 1995 -  Modified the LabWindows/CVI instrument driver to use    */
  25. /*                   VISA I/O calls.                                         */
  26. /*                   Modified by: JBS, National Instruments, Austin, TX      */
  27. /*                                                                           */
  28. /*      Sept 1995 -  The finished verson of the VISA port was mis-placed and */
  29. /*                   an unfinished version was inadvertently shipped with    */
  30. /*                   CVI 3.1.  This is a Beta Version of the VISA port and   */
  31. /*                   needs to be tested.  The driver should function properly*/
  32. /*                   because the port to VISA only involved changing the     */
  33. /*                   syntax of the I/O calls and Status tracking/reporting   */
  34. /*                   to match the VISA specs.                                */
  35. /*                   Modified by: JRO, National Instruments, Austin, TX      */
  36. /*                                                                           */
  37. /*      Sept 1995 -  Changes to the VISA driver were tested and the following*/
  38. /*                   fixes were made to the instrument driver: Timeout values*/
  39. /*                   changed in the _multiMeas and _fetchMeas functions to   */
  40. /*                   match millisecond units.  Fixed format specifier errors */
  41. /*                   in the _fetchMeas and _checkInstrStatus functions by    */
  42. /*                   changing %d to %d[b2] in the Fmt statements.  Fixed the */
  43. /*                   read count in the viRead statements in the _multiMeas   */
  44. /*                   and _singleMeas functions. Removed the function         */
  45. /*                   localRemote because the commands used are for the RS232 */
  46. /*                   interface which is not supported by this driver.        */
  47. /*                                                                           */
  48. /*                   Modified by: ELH , National Instruments, Austin, TX      */
  49. /*                                                                           */
  50. /* ========================================================================= */
  51.  
  52. /*****************************************************************************/
  53. /*= INSTRUMENT-DEPENDENT COMMAND ARRAYS =====================================*/
  54. /*****************************************************************************/
  55. static ViString funcStr[] = {"VOLT:AC", "VOLT", "VOLT:RAT", "CURR:AC", "CURR", "RES","FRES",    
  56.                              "FREQ", "PER", "CONT", "DIOD"}; 
  57. static ViString func2Str[] = {"VOLT:AC","VOLT","VOLT:RAT","CURR:AC","CURR","RES","FRES",    
  58.                               "FREQ:VOLT" ,"PER:VOLT"};
  59. static ViString resolStr[] = {"MAX","DEF","MIN"};
  60. static ViString resolModeStr[] = {"MIN","MAX"};
  61. static ViString mathOpStr[] = {"NULL","AVER","DB","DBM","LIM"};
  62. static ViString trigSrceStr[] = {"IMM", "EXT", "BUS"};
  63. static ViString terminalsStr[] = {"REAR","FRON"};
  64. static ViString autoZeroStr[] = {"OFF","ON","ONCE"};
  65. static ViString autoImpedStr[] = {"OFF","ON"};
  66. static ViString beeperState[] = {"OFF","ON"};
  67. static ViReal64 funLowRange[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 3.0, 0.0000033};
  68. static ViReal64 funHighRange[] = {100.0, 100.0, 0.0, 3.0, 3.0, 100000000.0, 100000000.0,
  69.                                   300000.0, 0.33};
  70.   
  71. /*****************************************************************************/
  72. /*= INSTRUMENT-DEPENDENT STATUS/RANGE STRUCTURE  ============================*/
  73. /*****************************************************************************/
  74. /* hp34401a_stringValPair is used in the hp34401a_errorMessage function      */
  75. /* hp34401a_statusDataRanges is used to track session dependent status & ranges*/
  76. /*===========================================================================*/
  77. typedef struct  hp34401a_stringValPair
  78. {
  79.    ViStatus stringVal;
  80.    ViString stringName;
  81. }  hp34401a_tStringValPair;
  82.  
  83. struct hp34401a_statusDataRanges {
  84.     ViInt16 triggerMode;
  85.     ViInt16 val2;
  86.     ViInt16 val3;
  87.     ViChar instrDriverRevision[256];
  88. };
  89.  
  90. typedef struct hp34401a_statusDataRanges *hp34401a_instrRange;
  91.  
  92. /*****************************************************************************/
  93. /*= UTILITY ROUTINE DECLARATIONS (Non-Exportable Functions) =================*/
  94. /*****************************************************************************/
  95. ViBoolean hp34401a_invalidViBooleanRange (ViBoolean val);
  96. ViBoolean hp34401a_invalidViInt16Range (ViInt16 val, ViInt16 min, ViInt16 max);
  97. ViBoolean hp34401a_invalidViInt32Range (ViInt32 val, ViInt32 min, ViInt32 max);
  98. ViBoolean hp34401a_invalidViUInt16Range (ViUInt16 val, ViUInt16 min, ViUInt16 max);
  99. ViBoolean hp34401a_invalidViUInt32Range (ViUInt32 val, ViUInt32 min, ViUInt32 max);
  100. ViBoolean hp34401a_invalidViReal32Range (ViReal32 val, ViReal32 min, ViReal32 max);
  101. ViBoolean hp34401a_invalidViReal64Range (ViReal64 val, ViReal64 min, ViReal64 max);
  102. ViStatus hp34401a_initCleanUp (ViSession openRMSession, ViPSession openInstrSession, ViStatus currentStatus);
  103. ViStatus hp34401a_readToFile (ViSession instrSession, ViString filename, ViUInt32 readBytes, ViPUInt32 retCount);
  104. ViStatus hp34401a_writeFromFile (ViSession instrSession, ViString filename, ViUInt32 writeBytes, ViPUInt32 retCount);
  105. ViStatus hp34401a_defaultInstrSetup (ViSession openInstrSession);
  106. ViInt16 hp34401a_checkInstrStatus (ViStatus instrSession);
  107. ViInt16 hp34401a_stringToInt (ViChar *array_of_strings[],ViInt16 start, ViInt16 stop,
  108.                                 ViChar *string,ViInt16 * index);
  109.  
  110. /*****************************************************************************/
  111. /*====== USER-CALLABLE FUNCTIONS (Exportable Functions) =====================*/
  112. /*****************************************************************************/
  113.  
  114. /*===========================================================================*/
  115. /* Function: Initialize                                                      */
  116. /* Purpose:  This function opens the instrument, queries the instrument      */
  117. /*           for its ID, and initializes the instrument to a known state.    */
  118. /*===========================================================================*/
  119. ViStatus _VI_FUNC hp34401a_init (ViRsrc resourceName, ViBoolean IDQuery,
  120.                     ViBoolean reset, ViPSession instrSession)
  121. {
  122.     ViStatus hp34401a_status = VI_SUCCESS;
  123.     ViUInt32 retCnt = 0;
  124.     ViByte rdBuffer[BUFFER_SIZE];
  125.     ViSession rmSession = 0;
  126.  
  127.     /*- Check input parameter ranges ----------------------------------------*/
  128.     if (hp34401a_invalidViBooleanRange (IDQuery))
  129.         return VI_ERROR_PARAMETER2;
  130.     if (hp34401a_invalidViBooleanRange (reset))
  131.         return VI_ERROR_PARAMETER3;
  132.  
  133.     /*- Open instrument session ---------------------------------------------*/
  134.     if ((hp34401a_status = viOpenDefaultRM (&rmSession)) < 0)
  135.         return hp34401a_status;
  136.  
  137.     if ((hp34401a_status = viOpen (rmSession, resourceName, VI_NULL, VI_NULL, instrSession)) < 0) {
  138.         viClose (rmSession);
  139.         return hp34401a_status;
  140.     }
  141.  
  142.     /*- Configure VISA Formatted I/O ----------------------------------------*/
  143.     if ((hp34401a_status = viSetAttribute (*instrSession, VI_ATTR_TMO_VALUE, 10000)) < 0)
  144.         return hp34401a_initCleanUp (rmSession, instrSession, hp34401a_status);
  145.     if ((hp34401a_status = viSetBuf (*instrSession, VI_READ_BUF|VI_WRITE_BUF, 4000)) < 0)
  146.         return hp34401a_initCleanUp (rmSession, instrSession, hp34401a_status);
  147.     if ((hp34401a_status = viSetAttribute (*instrSession, VI_ATTR_WR_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS)) < 0)
  148.         return hp34401a_initCleanUp (rmSession, instrSession, hp34401a_status);
  149.     if ((hp34401a_status = viSetAttribute (*instrSession, VI_ATTR_RD_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS)) < 0)
  150.         return hp34401a_initCleanUp (rmSession, instrSession, hp34401a_status);
  151.  
  152.     /*- Identification Query ------------------------------------------------*/
  153.     if (IDQuery) {
  154.         if ((hp34401a_status = viWrite (*instrSession, "*IDN?", 5, &retCnt)) < 0)
  155.             return hp34401a_initCleanUp (rmSession, instrSession, hp34401a_status);
  156.         if ((hp34401a_status = viRead (*instrSession, rdBuffer, BUFFER_SIZE, &retCnt)) < 0)
  157.             return hp34401a_status;
  158.  
  159.         Scan (rdBuffer, "HEWLETT-PACKARD,34401A");
  160.         if (NumFmtdBytes () != 22) 
  161.             return hp34401a_initCleanUp (rmSession, instrSession, VI_ERROR_FAIL_ID_QUERY);
  162.     }
  163.  
  164.     /*- Reset instrument ----------------------------------------------------*/
  165.     if (reset) {
  166.         if ((hp34401a_status = hp34401a_reset (*instrSession)) < 0)
  167.             return hp34401a_initCleanUp (rmSession, instrSession, hp34401a_status);
  168.     }       
  169.     else  /*- Send Default Instrument Setup ---------------------------------*/
  170.         if ((hp34401a_status = hp34401a_defaultInstrSetup (*instrSession)) < 0)
  171.             return hp34401a_initCleanUp (rmSession, instrSession, hp34401a_status);
  172.                 
  173.     return hp34401a_status;
  174. }
  175.  
  176. /* ========================================================================= */
  177. /* Function: hp34401a_conf                                                   */
  178. /* Purpose: Configure hp34401 Multimeter.                                    */
  179. /* ========================================================================= */
  180. ViStatus _VI_FUNC hp34401a_conf (ViSession instrSession, ViInt16 func,
  181.                         ViBoolean autorange, ViReal64 range, ViInt16 resol)
  182. {
  183.     ViStatus    hp34401a_status = VI_SUCCESS;
  184.     ViUInt32    retCnt = 0;
  185.     ViChar      wrtBuf[256];
  186.  
  187.     if (hp34401a_invalidViInt16Range (func, 0, 10) )
  188.         return VI_ERROR_PARAMETER2;
  189.     if (hp34401a_invalidViInt16Range (autorange, 0, 1) )
  190.         return VI_ERROR_PARAMETER3;
  191.     if (autorange == VI_OFF)
  192.         if (func < 9 && func != 2)
  193.             if (hp34401a_invalidViReal64Range (range, funLowRange[func], funHighRange[func]))
  194.                 return VI_ERROR_PARAMETER4;
  195.     if (hp34401a_invalidViInt16Range (resol, 0, 2))
  196.         return VI_ERROR_PARAMETER5;
  197.         
  198.     /*  Configure the test  */
  199.     if (func == 9 || func == 10)  {
  200.         Fmt (wrtBuf, "%s<:CONF:%s\r\n", funcStr[func]);
  201.         if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  202.             return hp34401a_status;
  203.     }
  204.     else  {
  205.         /*  Configure the measurement  */
  206.         if (autorange == VI_ON)
  207.             Fmt (wrtBuf, "%s<:CONF:%s AUTO,%s\r\n", funcStr[func], resolStr[resol]);
  208.         else
  209.             Fmt (wrtBuf, "%s<:CONF:%s %f,%s\r\n", funcStr[func], range, resolStr[resol]);
  210.         if ((hp34401a_status = viWrite(instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  211.             return hp34401a_status;
  212.     }
  213.     
  214.     return hp34401a_status;
  215. }
  216.  
  217. /* ========================================================================= */
  218. /* Function: Trigger configuration                                           */
  219. /* Purpose: Configure Trigger                                                */
  220. /* ========================================================================= */
  221. ViStatus _VI_FUNC hp34401a_confTrig (ViSession instrSession, ViInt16 trig_srce,
  222.                              ViBoolean auto_delay, ViReal64 trig_delay,
  223.                              ViInt32 trig_cnt, ViInt32 samp_cnt)
  224. {
  225.     ViStatus    hp34401a_status = VI_SUCCESS;
  226.     ViUInt32    retCnt = 0;
  227.     ViChar      wrtBuf[256];
  228.  
  229.     if (hp34401a_invalidViInt16Range (trig_srce, 0, 2))
  230.         return VI_ERROR_PARAMETER2;
  231.     if (hp34401a_invalidViInt16Range (auto_delay, 0, 1))
  232.         return VI_ERROR_PARAMETER3;
  233.     if (hp34401a_invalidViReal64Range (trig_delay, 0.0, 3600.0))
  234.         return VI_ERROR_PARAMETER4;
  235.     if (hp34401a_invalidViInt32Range (trig_cnt, 1L, 50000L))
  236.         return VI_ERROR_PARAMETER5;
  237.     if (hp34401a_invalidViInt32Range (samp_cnt, 1L, 50000L))
  238.         return VI_ERROR_PARAMETER6;
  239.         
  240.     if (!auto_delay)
  241.         /*  Auto-delay off  */
  242.         Fmt (wrtBuf, "%s<:TRIG:SOUR %s;DEL %f;COUN %d[b4];:SAMP:COUN %d[b4]\r\n", trigSrceStr[trig_srce], trig_delay,
  243.         trig_cnt, samp_cnt);
  244.     else
  245.         Fmt (wrtBuf, "%s<:TRIG:SOUR %s;COUN %d[b4];DEL:AUTO ON;:SAMP:COUN %d[b4]\r\n", trigSrceStr[trig_srce], trig_cnt,
  246.         samp_cnt);
  247.     if ((hp34401a_status = viWrite(instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)  
  248.         return hp34401a_status;
  249.  
  250.     return hp34401a_status;
  251. }
  252.  
  253. /* ========================================================================= */
  254. /* Function: Aperture Time                                                   */
  255. /* Purpose: Configure aperture time                                          */
  256. /* ========================================================================= */
  257. ViStatus _VI_FUNC hp34401a_confAperTime (ViSession instrSession, ViInt16 func,
  258.                                   ViReal64 aper_time)
  259. {
  260.     ViStatus hp34401a_status = VI_SUCCESS;
  261.     ViUInt32 retCnt = 0;
  262.     ViByte rdBuf[BUFFER_SIZE], wrtBuf[BUFFER_SIZE] ;
  263.  
  264.     if (hp34401a_invalidViInt16Range (func, 7, 8))
  265.         return VI_ERROR_PARAMETER2;
  266.     if (hp34401a_invalidViReal64Range (aper_time, 0.00001, 1.0))
  267.         return VI_ERROR_PARAMETER3;
  268.         
  269.     Fmt (wrtBuf, "%s<:%s:APER %f\r\n", funcStr[func], aper_time);
  270.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  271.         return hp34401a_status;
  272.         
  273.     return hp34401a_status;
  274. }
  275.  
  276. /* ========================================================================= */
  277. /* Function: Intergration Time Configuration                                 */
  278. /* Purpose: Configure intergration time                                      */
  279. /* ========================================================================= */
  280. ViStatus _VI_FUNC hp34401a_confIntegratTime (ViSession instrSession, ViInt16 func,
  281.                                       ViReal64 integrat_time)
  282. {
  283.     ViStatus hp34401a_status = VI_SUCCESS;
  284.     ViUInt32 retCnt = 0;
  285.     ViByte wrtBuf[BUFFER_SIZE];
  286.  
  287.     if (func != 1 && func != 4 && func != 5 && func != 6)  
  288.         return VI_ERROR_PARAMETER2;
  289.     if (hp34401a_invalidViReal64Range (integrat_time, 0.02, 100.0))
  290.         return VI_ERROR_PARAMETER3;
  291.         
  292.     Fmt (wrtBuf, "%s<:%s:NPLC %f\r\n", funcStr[func], integrat_time);
  293.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  294.         return hp34401a_status;
  295.  
  296.     return hp34401a_status;
  297. }
  298.  
  299. /* ========================================================================= */
  300. /* Function: Misc. Configuration                                             */
  301. /* Purpose: Performs other configuraion not in the above funcitons.          */
  302. /* ========================================================================= */
  303. ViStatus _VI_FUNC hp34401a_confMisc (ViSession instrSession, ViInt16 auto_zero,
  304.                             ViReal64 bandwidth, ViBoolean auto_imped)
  305.  
  306. {
  307.     ViStatus hp34401a_status = VI_SUCCESS;
  308.     ViUInt32 retCnt = 0;
  309.     ViByte wrtBuf[BUFFER_SIZE] ;
  310.      
  311.     if (hp34401a_invalidViInt16Range (auto_zero, 0, 2))
  312.         return VI_ERROR_PARAMETER2;
  313.     if (hp34401a_invalidViReal64Range (bandwidth, 3.0,200))
  314.         return VI_ERROR_PARAMETER3;
  315.     if (hp34401a_invalidViBooleanRange (auto_imped))
  316.         return VI_ERROR_PARAMETER4;
  317.         
  318.     Fmt (wrtBuf, "%s<:ZERO:AUTO %s\r\n", autoZeroStr[auto_zero]);
  319.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  320.         return hp34401a_status;
  321.     Fmt (wrtBuf, "%s<:INP:IMP:AUTO %s\r\n", autoImpedStr[auto_imped]);
  322.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  323.         return hp34401a_status;
  324.     Fmt (wrtBuf, "%s<:DET:BAND %f\r\n", bandwidth);
  325.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  326.         return hp34401a_status;
  327.  
  328.     return hp34401a_status;
  329. }
  330.  
  331. /* ========================================================================= */
  332. /* Function: Wait for trigger                                                */
  333. /* Purpose: Waiting for trigger                                              */
  334. /* ========================================================================= */
  335. ViStatus _VI_FUNC hp34401a_waitForTrigger (ViSession instrSession)
  336. {
  337.     ViStatus hp34401a_status = VI_SUCCESS;
  338.     ViUInt32 retCnt = 0;
  339.     ViByte wrtBuf[BUFFER_SIZE] ;
  340.  
  341.     if ((hp34401a_status = viWrite (instrSession, ":INIT\r\n", 7,&retCnt)) < 0)
  342.         return hp34401a_status;
  343.     /*  Check the Status Byte of the instrument for proper execution.  */
  344.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  345.         return hp34401a_status;
  346.     return hp34401a_status;
  347. }
  348.  
  349. /* ========================================================================= */
  350. /* Function: Software trigger                                                */
  351. /* Purpose: Software triggers the instrument                                 */
  352. /* ========================================================================= */
  353. ViStatus _VI_FUNC hp34401a_softTrig (ViSession instrSession)
  354. {
  355.     ViStatus hp34401a_status = VI_SUCCESS;
  356.     ViUInt32 retCnt = 0;
  357.     ViByte rdBuf[BUFFER_SIZE], wrtBuf[BUFFER_SIZE] ;
  358.  
  359.     if ((hp34401a_status= viWrite (instrSession, "*TRG\r\n", 6, &retCnt)) < 0 )
  360.         return hp34401a_status;
  361.     /*  Check the Status Byte of the instrument for proper execution.  */
  362.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  363.         return hp34401a_status;
  364.     return hp34401a_status;
  365. }
  366.  
  367. /* ========================================================================= */
  368. /* Function: Abort measurement                                               */
  369. /* Purpose: Abort measurement                                                */
  370. /* ========================================================================= */
  371. ViStatus _VI_FUNC hp34401a_abortMeas (ViSession instrSession)
  372. {
  373.     ViStatus hp34401a_status = VI_SUCCESS;
  374.     ViUInt32 retCnt = 0;
  375.     ViByte rdBuf[BUFFER_SIZE], wrtBuf[BUFFER_SIZE] ;
  376.  
  377.     if ((hp34401a_status= viWrite (instrSession, ":ABOR\r\n", 7, &retCnt)) < 0 )
  378.         return hp34401a_status;
  379.     /*  Check the Status Byte of the instrument for proper execution.  */
  380.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  381.         return hp34401a_status;
  382.     return hp34401a_status;
  383. }
  384.  
  385. /* ========================================================================= */
  386. /* Function: Beeper                                                          */
  387. /* Purpose: Configure beeper                                                 */
  388. /* ========================================================================= */
  389. ViStatus _VI_FUNC hp34401a_beeper (ViSession instrSession, ViBoolean on_off,
  390.                           ViBoolean instr_beep)
  391. {
  392.     ViStatus hp34401a_status = VI_SUCCESS;
  393.     ViUInt32 retCnt = 0;
  394.     ViByte  wrtBuf[BUFFER_SIZE];
  395.  
  396.     if (hp34401a_invalidViBooleanRange (on_off))
  397.         return VI_ERROR_PARAMETER2;
  398.     if (hp34401a_invalidViInt16Range (instr_beep, 0, 1))
  399.         return VI_ERROR_PARAMETER3;
  400.         
  401.     if (instr_beep == 1)
  402.         Fmt (wrtBuf, "%s<SYST:BEEP:STAT %s;:SYST:BEEP\r\n", beeperState[on_off]);
  403.     else
  404.         Fmt (wrtBuf, "%s<SYST:BEEP:STAT %s\r\n", beeperState[on_off]);
  405.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  406.         return hp34401a_status;
  407.         
  408.     return hp34401a_status;
  409. }
  410.  
  411. /* ========================================================================= */
  412. /* Function: Single Measurement                                              */
  413. /* Purpose: Configure single measurement                                     */
  414. /* ========================================================================= */
  415. ViStatus _VI_FUNC hp34401a_singleMeas (ViSession instrSession, ViReal64 *reading)
  416. {
  417.     ViStatus hp34401a_status = VI_SUCCESS;
  418.     ViUInt32 retCnt = 0;
  419.     ViByte wrtBuf[BUFFER_SIZE],rdBuf[BUFFER_SIZE];
  420.       
  421.     if ((hp34401a_status = viWrite (instrSession, ":INIT;:FETC?\r\n", 14,&retCnt)) < 0)
  422.         return hp34401a_status;
  423.     if ((hp34401a_status = viRead (instrSession, rdBuf, MAX_CMD_LENGTH,&retCnt)) < 0)
  424.         return hp34401a_status;
  425.     if (Scan (rdBuf, "%s>%f", reading) != 1)  {
  426.         hp34401a_status = VI_ERROR_INTERPRETING_RESPONSE;
  427.         return hp34401a_status;
  428.     }
  429.  
  430.     return hp34401a_status;
  431. }
  432.  
  433. /* ========================================================================= */
  434. /* Function: Multiple Measurement                                            */
  435. /* Purpose: Configure multiple measurement                                   */
  436. /* ========================================================================= */
  437. ViStatus _VI_FUNC hp34401a_multiMeas (ViSession instrSession, ViInt16 timeout,
  438.                               ViInt16 *num_readings, ViReal64 readings[])
  439. {
  440.     ViStatus hp34401a_status = VI_SUCCESS;
  441.     ViUInt32 retCnt = 0;
  442.     ViByte rdBuf[BUFFER_SIZE], wrtBuf[BUFFER_SIZE] ;
  443.     ViReal64 trig_cnt = 0;
  444.     ViInt16 samp_cnt = 0;
  445.  
  446.     if (hp34401a_invalidViInt16Range (timeout, 0, 1000000))
  447.         return VI_ERROR_PARAMETER2;
  448.         
  449.     if ((hp34401a_status = viWrite (instrSession, ":TRIG:COUN?;:SAMP:COUN?\r\n", 25,&retCnt)) < 0)
  450.         return hp34401a_status;
  451.     if ((hp34401a_status = viRead (instrSession, rdBuf, MAX_CMD_LENGTH, &retCnt)) < 0)
  452.         return hp34401a_status;
  453.     if (Scan (rdBuf, "%s>%f[x]%d[b2]", &trig_cnt, &samp_cnt) != 2) {  
  454.         hp34401a_status = VI_ERROR_INTERPRETING_RESPONSE;
  455.         return hp34401a_status;
  456.     }
  457.     *num_readings = (ViInt16)((ViReal64)samp_cnt * trig_cnt);
  458.     if ((hp34401a_status = viWrite (instrSession, ":INIT;:FETC?\r\n", 14,&retCnt)) < 0 )
  459.         return hp34401a_status;
  460.     if ((hp34401a_status = viSetAttribute (instrSession, VI_ATTR_TMO_VALUE,timeout)) < 0)
  461.         return hp34401a_status;
  462.     if ((hp34401a_status = viRead (instrSession, rdBuf, MAX_CMD_LENGTH, &retCnt)) < 0)  {
  463.         if ((hp34401a_status = viSetAttribute (instrSession, VI_ATTR_TMO_VALUE,timeout)) < 0)
  464.             return hp34401a_status;
  465.         return hp34401a_status;
  466.     }
  467.     if ((hp34401a_status = viSetAttribute (instrSession, VI_ATTR_TMO_VALUE,timeout)) < 0)
  468.         return hp34401a_status;
  469.     if (Scan (rdBuf, "%s>%*f[x]", *num_readings, readings) != 1)  {
  470.         hp34401a_status = VI_ERROR_INTERPRETING_RESPONSE;
  471.         return hp34401a_status;
  472.     }
  473.  
  474.     return hp34401a_status;
  475. }
  476.  
  477. /* ========================================================================= */
  478. /* Function: Active math operation                                           */
  479. /* Purpose: Activates the selected math operation.                           */
  480. /* ========================================================================= */
  481. ViStatus _VI_FUNC hp34401a_actMathOp (ViSession instrSession, ViInt16 math_op,
  482.                                ViBoolean state)
  483. {
  484.     ViStatus hp34401a_status = VI_SUCCESS;
  485.     ViUInt32 retCnt = 0;
  486.     ViByte  wrtBuf[BUFFER_SIZE] ;
  487.  
  488.     if (hp34401a_invalidViInt16Range (math_op, 0, 4))
  489.         return VI_ERROR_PARAMETER2;
  490.     if (hp34401a_invalidViInt16Range (state, 0, 1))
  491.         return VI_ERROR_PARAMETER3;
  492.         
  493.     Fmt (wrtBuf, "%s<:CALC:FUNC %s;STAT %d[b2]\r\n", mathOpStr[math_op], state);
  494.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  495.         return hp34401a_status;
  496.     /*  Check the Status Byte of the instrument for proper execution.  */
  497.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  498.         return hp34401a_status;
  499.         
  500.     return hp34401a_status;
  501. }
  502.  
  503. /* ========================================================================= */
  504. /* Function: Fetch Measurement                                               */
  505. /* Purpose: Send command to fetch results                                    */
  506. /* ========================================================================= */
  507. ViStatus _VI_FUNC hp34401a_fetchMeas (ViSession instrSession, ViInt16 timeout,
  508.                               ViInt16 *num_readings, ViReal64 readings[])
  509. {
  510.     ViStatus hp34401a_status = VI_SUCCESS;
  511.     ViUInt32 retCnt = 0;
  512.     ViByte rdBuf[BUFFER_SIZE], wrtBuf[BUFFER_SIZE] ;
  513.     ViInt16 samp_cnt;
  514.     ViReal64 trig_cnt;
  515.  
  516.     if (hp34401a_invalidViInt16Range (timeout, 0, 1000000))
  517.         return VI_ERROR_PARAMETER2;
  518.     if ((hp34401a_status = viWrite (instrSession, ":TRIG:COUN?;:SAMP:COUN?\r\n", 25, &retCnt)) < 0 )
  519.         return hp34401a_status;
  520.     if ((hp34401a_status = viRead (instrSession, rdBuf,MAX_CMD_LENGTH, &retCnt)) < 0 )
  521.         return hp34401a_status;
  522.     if (Scan (rdBuf, "%s>%f[x]%d[b2]", &trig_cnt, &samp_cnt) != 2)  {
  523.         hp34401a_status = VI_ERROR_INTERPRETING_RESPONSE;
  524.         return hp34401a_status;
  525.     }
  526.     *num_readings = (ViInt16)((ViReal64)samp_cnt * trig_cnt);
  527.     if ((hp34401a_status = viWrite (instrSession, ":FETC?\r\n", 8, &retCnt)) < 0 )
  528.         return hp34401a_status;
  529.     if ((hp34401a_status = viSetAttribute (instrSession, VI_ATTR_TMO_VALUE,timeout)) < 0)
  530.         return hp34401a_status;
  531.     if ((hp34401a_status = viRead (instrSession, rdBuf,MAX_CMD_LENGTH, &retCnt)) < 0 )  {
  532.             if ((hp34401a_status = viSetAttribute (instrSession, VI_ATTR_TMO_VALUE,timeout)) < 0)
  533.                 return hp34401a_status;
  534.             else hp34401a_status = VI_ERROR_TMO;
  535.         return hp34401a_status;
  536.     }
  537.     if ((hp34401a_status = viSetAttribute (instrSession, VI_ATTR_TMO_VALUE,timeout)) < 0)
  538.         return hp34401a_status;
  539.     if (Scan (rdBuf, "%s>%*f[x]", *num_readings, readings) != 1) 
  540.         return VI_ERROR_INTERPRETING_RESPONSE;
  541.     /*  Check the Status Byte of the instrument for proper execution.  */
  542.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  543.         return hp34401a_status;
  544.         
  545.     return hp34401a_status;
  546. }
  547.  
  548. /* ========================================================================= */
  549. /* Function: Configure null measurement                                      */
  550. /* Purpose: Making null measurement                                          */
  551. /* ========================================================================= */
  552. ViStatus _VI_FUNC hp34401a_confNull (ViSession instrSession, ViReal64 null_val)
  553. {
  554.     ViStatus hp34401a_status = VI_SUCCESS;
  555.     ViUInt32 retCnt = 0;
  556.     ViByte  wrtBuf[BUFFER_SIZE] ;
  557.  
  558.     Fmt (wrtBuf, "%s<:CALC:NULL:OFFS %f\r\n", null_val);
  559.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  560.         return hp34401a_status;
  561.     /*  Check the Status Byte of the instrument for proper execution.  */
  562.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  563.         return hp34401a_status;
  564.         
  565.     return hp34401a_status;
  566. }
  567.  
  568. /* ========================================================================= */
  569. /* Function: dB measurement                                                  */
  570. /* Purpose: Making dB measurement                                            */
  571. /* ========================================================================= */
  572. ViStatus _VI_FUNC hp34401a_confDbMeas (ViSession instrSession, ViReal64 db_ref)
  573. {
  574.     ViStatus hp34401a_status = VI_SUCCESS;
  575.     ViUInt32 retCnt = 0;
  576.     ViByte  wrtBuf[BUFFER_SIZE] ;
  577.  
  578.     if (hp34401a_invalidViReal64Range (db_ref, 0.0, 200.0))
  579.         return VI_ERROR_PARAMETER2;
  580.         
  581.     Fmt (wrtBuf, "%s<:CALC:DB:REF %f\r\n", db_ref);
  582.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  583.         return hp34401a_status;
  584.     /*  Check the Status Byte of the instrument for proper execution.  */
  585.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  586.         return hp34401a_status;
  587.         
  588.     return hp34401a_status;
  589. }
  590.  
  591. /* ========================================================================= */
  592. /* Function: dBm measurement                                                 */
  593. /* Purpose: Making dB measurement                                            */
  594. /* ========================================================================= */
  595. ViStatus _VI_FUNC hp34401a_confDbmMeas (ViSession instrSession, ViInt16 dbm_ref)
  596. {
  597.     ViStatus hp34401a_status = VI_SUCCESS;
  598.     ViUInt32 retCnt = 0;
  599.     ViByte  wrtBuf[BUFFER_SIZE] ;
  600.  
  601.     if (hp34401a_invalidViReal64Range (dbm_ref, 0.0, 8000.0))
  602.         return VI_ERROR_PARAMETER2;
  603.  
  604.     Fmt (wrtBuf, "%s<:CALC:DBM:REF %d[b2]\r\n", dbm_ref);
  605.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  606.         return hp34401a_status;
  607.     /*  Check the Status Byte of the instrument for proper execution.  */
  608.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  609.         return hp34401a_status;
  610.         
  611.     return hp34401a_status;
  612. }
  613.  
  614. /* ========================================================================= */
  615. /* Function: Limit test                                                      */
  616. /* Purpose: Perform pass/fail test on the limits specified                   */
  617. /* ========================================================================= */
  618. ViStatus _VI_FUNC hp34401a_confLimitTest (ViSession instrSession, ViReal64 upper_lim,
  619.                                    ViReal64 lower_lim)
  620. {
  621. ViStatus hp34401a_status = VI_SUCCESS;
  622. ViUInt32 retCnt = 0;
  623. ViByte  wrtBuf[BUFFER_SIZE] ;
  624.  
  625.     Fmt (wrtBuf, "%s<:CALC:LIM:UPP %f;LOW %f\r\n", upper_lim, lower_lim);
  626.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  627.         return hp34401a_status;
  628.     /*  Check the Status Byte of the instrument for proper execution.  */
  629.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  630.         return hp34401a_status;
  631.         
  632.     return hp34401a_status;
  633. }
  634.  
  635. /* ========================================================================= */
  636. /* Function: Display                                                         */
  637. /* Purpose: Configure the front panel                                        */
  638. /* ========================================================================= */
  639. ViStatus _VI_FUNC hp34401a_display (ViSession instrSession, ViBoolean on_off,
  640.                            ViChar message[], ViBoolean clear)
  641. {
  642.     ViStatus hp34401a_status = VI_SUCCESS;
  643.     ViUInt32 retCnt = 0;
  644.     ViByte  wrtBuf[BUFFER_SIZE];
  645.  
  646.     if (hp34401a_invalidViInt16Range (on_off, 0, 1))
  647.         return VI_ERROR_PARAMETER2;
  648.     if (StringLength (message) > 12)
  649.         return VI_ERROR_PARAMETER3;
  650.     if (hp34401a_invalidViInt16Range (clear, 0, 1))
  651.         return VI_ERROR_PARAMETER4;
  652.         
  653.     if (clear == 1)
  654.         Fmt (wrtBuf, "%s<:DISP:TEXT:CLE;:DISP:STAT %d[b2]\r\n", on_off);
  655.     else
  656.         Fmt (wrtBuf, "%s<:DISP:TEXT \"%s\";:DISP:STAT %d[b2]\r\n", message, on_off);
  657.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  658.         return hp34401a_status;
  659.     /*  Check the Status Byte of the instrument for proper execution.  */
  660.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  661.         return hp34401a_status;
  662.         
  663.     return hp34401a_status;
  664. }
  665.  
  666. /* ========================================================================= */
  667. /* Function: Check terminals                                                 */
  668. /* Purpose: Check whether the front terminal are being used                  */
  669. /* ========================================================================= */
  670. ViStatus _VI_FUNC hp34401a_checkTerminals (ViSession instrSession, ViInt16 *terminals)
  671. {
  672.     ViStatus hp34401a_status = VI_SUCCESS;
  673.     ViUInt32 retCnt = 0;
  674.     ViByte  wrtBuf[BUFFER_SIZE],rdBuf[BUFFER_SIZE];
  675.     ViChar terminals_resp[5];
  676.  
  677.     if ((hp34401a_status= viWrite (instrSession, ":ROUTE:TERM?\r\n", 14, &retCnt)) < 0)
  678.         return hp34401a_status;
  679.     if ((hp34401a_status = viRead (instrSession, rdBuf, MAX_CMD_LENGTH, &retCnt)) < 0)
  680.         return hp34401a_status;
  681.     if (Scan (rdBuf, "%s>%s", terminals_resp) != 1)
  682.         return VI_ERROR_INTERPRETING_RESPONSE;
  683.     /*  Convert the string response to an integer.  */
  684.     if (hp34401a_stringToInt (terminalsStr, 0, 1, terminals_resp, terminals) != 0)
  685.         return hp34401a_status;
  686.  
  687.     return hp34401a_status;
  688. }
  689.  
  690. /* ========================================================================= */
  691. /* Function: Check SCPI                                                      */
  692. /* Purpose: Query SCPI vertion                                               */
  693. /* ========================================================================= */
  694. ViStatus _VI_FUNC hp34401a_checkScpiVersion (ViSession instrSession, ViInt16 *year,
  695.                                              ViInt16 *version)
  696. {
  697.     ViStatus hp34401a_status = VI_SUCCESS;
  698.     ViUInt32 retCnt = 0;
  699.     ViByte  wrtBuf[BUFFER_SIZE],rdBuf[BUFFER_SIZE];
  700.  
  701.     if ((hp34401a_status= viWrite (instrSession, ":SYST:VERS?\r\n", 13,&retCnt)) < 0)
  702.         return hp34401a_status;
  703.     if ((hp34401a_status = viRead (instrSession, rdBuf, MAX_CMD_LENGTH,&retCnt)) < 0)
  704.         return hp34401a_status;
  705.     if (Scan (rdBuf, "%s>%d[xb2]%d[b2]", year, version) != 2)  
  706.         return VI_ERROR_INTERPRETING_RESPONSE;
  707.  
  708.     return hp34401a_status;
  709. }
  710.  
  711. /*===========================================================================*/
  712. /* Function: Write To Instrument                                             */
  713. /* Purpose:  This function writes a command string to the instrument.        */
  714. /*===========================================================================*/
  715. ViStatus _VI_FUNC hp34401a_writeInstrData (ViSession instrSession, ViString writeBuffer)
  716. {
  717.     ViStatus hp34401a_status = VI_SUCCESS;
  718.     
  719.     if ((hp34401a_status = viPrintf (instrSession, "%s", writeBuffer)) < 0)
  720.         return hp34401a_status;
  721.  
  722.     return hp34401a_status;
  723. }
  724.  
  725. /*===========================================================================*/
  726. /* Function: Read Instrument Buffer                                          */
  727. /* Purpose:  This function reads the output buffer of the instrument.        */
  728. /*===========================================================================*/
  729. ViStatus _VI_FUNC hp34401a_readInstrData (ViSession instrSession, ViInt16 numBytes,
  730.                     ViChar rdBuf[], ViPInt32 bytesRead)
  731. {
  732.     ViStatus hp34401a_status = VI_SUCCESS;
  733.     *bytesRead = 0L;
  734.         
  735.     if ((hp34401a_status = viRead (instrSession, rdBuf, numBytes, bytesRead)) < 0)
  736.         return hp34401a_status;
  737.  
  738.     return hp34401a_status;
  739. }
  740.  
  741. /*===========================================================================*/
  742. /* Function: Reset                                                           */
  743. /* Purpose:  This function resets the instrument.  If the reset function     */
  744. /*           is not supported by the instrument, this function returns       */
  745. /*           the warning VI_WARN_NSUP_RESET.                                 */
  746. /*===========================================================================*/
  747. ViStatus _VI_FUNC hp34401a_reset (ViSession instrSession)
  748. {
  749.     ViUInt32 retCnt = 0;
  750.     ViStatus hp34401a_status = VI_SUCCESS;
  751.  
  752.     /*  Initialize the instrument to a known state.  */
  753.     if ((hp34401a_status = viWrite (instrSession, "*CLS\r\n", 6, &retCnt)) < 0)
  754.         return hp34401a_status;
  755.  
  756.     if ((hp34401a_status = hp34401a_defaultInstrSetup (instrSession)) < 0)  
  757.         return hp34401a_status;
  758.         
  759.      /*  Set timeout to 10 seconds  */
  760.     hp34401a_status = viSetAttribute (instrSession, VI_ATTR_TMO_VALUE,10000);
  761.    
  762.     return hp34401a_status;
  763. }
  764.  
  765. /*===========================================================================*/
  766. /* Function: Self-Test                                                       */
  767. /* Purpose:  This function executes the instrument self-test and returns     */
  768. /*           the result. If the self test function is not supported by the   */
  769. /*           instrument, this function returns the warning                   */
  770. /*           VI_WARN_NSUP_SELF_TEST.                                         */
  771. /*===========================================================================*/
  772. ViStatus _VI_FUNC hp34401a_selfTest (ViSession instrSession, ViPInt16 testResult,
  773.                     ViChar testMessage[])
  774. {
  775.     ViUInt32 retCnt = 0;
  776.     ViStatus hp34401a_status = VI_SUCCESS;
  777.     
  778.     if ((hp34401a_status = viWrite (instrSession, "*TST?\r\n", 7, &retCnt)) < 0)
  779.         return hp34401a_status;
  780.  
  781.     if ((hp34401a_status = viScanf (instrSession, "%hd", testResult)) < 0)
  782.         return hp34401a_status;
  783.     Fmt (testMessage, "%s<%d[b2]", *testResult);
  784.     
  785.     return hp34401a_status;
  786. }
  787.  
  788. /*===========================================================================*/
  789. /* Function: Error Query                                                     */
  790. /* Purpose:  This function queries the instrument error queue, and returns   */
  791. /*           the result. If the error query function is not supported by the */
  792. /*           instrument, this function returns the warning                   */
  793. /*           VI_WARN_NSUP_ERROR_QUERY.                                       */
  794. /*===========================================================================*/
  795. ViStatus _VI_FUNC hp34401a_errorQuery (ViSession instrSession, ViPInt32 errCode,
  796.                     ViChar errMessage[])
  797. {
  798.     ViUInt32 retCnt = 0;
  799.     ViStatus hp34401a_status = VI_SUCCESS;
  800.  
  801.     if ((hp34401a_status = viWrite (instrSession, ":SYST:ERR?\r\n", 12, &retCnt)) < 0)
  802.         return hp34401a_status;
  803.     
  804.     if ((hp34401a_status = viScanf (instrSession, "%ld,\"%[^\"]", errCode, errMessage)) < 0)
  805.         return hp34401a_status;
  806.  
  807.  
  808.     return hp34401a_status;
  809. }
  810.  
  811. /*===========================================================================*/
  812. /* Function: Error Message                                                   */
  813. /* Purpose:  This function translates the error return value from the        */
  814. /*           instrument driver into a user-readable string.                  */
  815. /*===========================================================================*/
  816. ViStatus _VI_FUNC hp34401a_errorMessage (ViSession instrSession, ViStatus errorCode,
  817.                     ViChar errMessage[])
  818. {
  819.     ViStatus hp34401a_status = VI_SUCCESS;
  820.     ViInt16 i;
  821.     static hp34401a_tStringValPair statusDescArray[] = {
  822.         {VI_WARN_NSUP_ID_QUERY,     "WARNING: ID Query not supported"},
  823.         {VI_WARN_NSUP_RESET,        "WARNING: Reset not supported"},
  824.         {VI_WARN_NSUP_SELF_TEST,    "WARNING: Self-test not supported"},
  825.         {VI_WARN_NSUP_ERROR_QUERY,  "WARNING: Error Query not supported"},     
  826.         {VI_WARN_NSUP_REV_QUERY,    "WARNING: Revision Query not supported"},
  827.         {VI_ERROR_PARAMETER1,   "ERROR: Parameter 1 out of range"},
  828.         {VI_ERROR_PARAMETER2,   "ERROR: Parameter 2 out of range"},
  829.         {VI_ERROR_PARAMETER3,   "ERROR: Parameter 3 out of range"},
  830.         {VI_ERROR_PARAMETER4,   "ERROR: Parameter 4 out of range"},
  831.         {VI_ERROR_PARAMETER5,   "ERROR: Parameter 5 out of range"},
  832.         {VI_ERROR_PARAMETER6,   "ERROR: Parameter 6 out of range"},
  833.         {VI_ERROR_PARAMETER7,   "ERROR: Parameter 7 out of range"},
  834.         {VI_ERROR_PARAMETER8,   "ERROR: Parameter 8 out of range"},
  835.         {VI_ERROR_FAIL_ID_QUERY,"ERROR: Identification query failed"},
  836.         {VI_ERROR_INV_RESPONSE, "ERROR: Interpreting instrument response"},
  837.         {VI_ERROR_FILE_OPEN,    "ERROR: Opening the specified file"},
  838.         {VI_ERROR_FILE_WRITE,   "ERROR: Writing to the specified file"},
  839.         {VI_ERROR_INTERPRETING_RESPONSE, "ERROR: Interpreting the instrument's response"},
  840.         {VI_ERROR_SECURITY_CODE,    "ERROR: Security code too long"},
  841.         {VI_ERROR_STAMP,    "ERROR: STAMP TOO LONG"},
  842.         {VI_ERROR_OUTOFF_RANGE, "ERROR: Data outoff range."},
  843.         {VI_NULL, VI_NULL}
  844.     };
  845.  
  846.     hp34401a_status = viStatusDesc (instrSession, errorCode, errMessage);
  847.     if (hp34401a_status == VI_WARN_UNKNOWN_STATUS) {
  848.         for (i=0; statusDescArray[i].stringName; i++) {
  849.             if (statusDescArray[i].stringVal == errorCode) {
  850.                 strcpy (errMessage, statusDescArray[i].stringName);
  851.                 return (VI_SUCCESS);
  852.             }
  853.         }
  854.         sprintf (errMessage, "Unknown Error 0x%08lX", errorCode);
  855.         return (VI_WARN_UNKNOWN_STATUS);
  856.     }
  857.     
  858.     hp34401a_status = VI_SUCCESS;
  859.     return hp34401a_status;
  860. }
  861.  
  862. /*===========================================================================*/
  863. /* Function: Revision Query                                                  */
  864. /* Purpose:  This function returns the driver and instrument revisions.      */
  865. /*           If the revision query function is not supported by the          */ 
  866. /*           instrument, this function returns the warning                   */
  867. /*           VI_WARN_NSUP_REV_QUERY.                                         */
  868. /*===========================================================================*/
  869. ViStatus _VI_FUNC hp34401a_revisionQuery (ViSession instrSession,
  870.                     ViChar driverRev[], ViChar instrRev[])
  871. {
  872.     ViUInt32 retCnt = 0;
  873.     ViStatus hp34401a_status = VI_SUCCESS;
  874.  
  875.     if ((hp34401a_status = viWrite (instrSession, "*IDN?", 5, &retCnt)) < 0)
  876.         return hp34401a_status;
  877.  
  878.     if ((hp34401a_status = viScanf (instrSession, "%*[^,],%*[^,],%*[^,],%[^\n]", instrRev)) < 0)
  879.         return hp34401a_status;
  880.  
  881.     strcpy (driverRev, hp34401a_REVISION);
  882.     
  883.     return hp34401a_status;
  884. }
  885.  
  886. /* ========================================================================= */
  887. /* Function: Secure/unsecure calibration                                     */
  888. /* Purpose: Switch to secure/insecure calibration                            */
  889. /* ========================================================================= */
  890. ViStatus _VI_FUNC hp34401a_calSecure (ViSession instrSession, ViChar security_code[], 
  891.                                     ViBoolean secure)
  892. {
  893. ViStatus hp34401a_status = VI_SUCCESS;
  894. ViUInt32 retCnt = 0;
  895. ViByte  wrtBuf[BUFFER_SIZE] ;
  896.  
  897.     if (StringLength (security_code) > 12)
  898.         return  VI_ERROR_PARAMETER2;
  899.     if (hp34401a_invalidViBooleanRange (secure))
  900.         return VI_ERROR_PARAMETER3;
  901.         
  902.     Fmt (wrtBuf, "%s<:CAL:SEC:STAT %d[b2],%s\r\n", secure, security_code);
  903.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  904.         return hp34401a_status;
  905.     /*  Check the Status Byte of the instrument for proper execution.  */
  906.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  907.         return hp34401a_status;
  908.         
  909.     return hp34401a_status;
  910. }
  911.  
  912.  
  913. /* ========================================================================= */
  914. /* Function: Calibrate code                                                  */
  915. /* Purpose: Allow user to change the security code                           */
  916. /* ========================================================================= */
  917. ViStatus _VI_FUNC hp34401a_calCode (ViSession instrSession, ViChar new_cal_code[])
  918. {
  919.     ViStatus hp34401a_status = VI_SUCCESS;
  920.     ViUInt32 retCnt = 0;
  921.     ViByte  wrtBuf[BUFFER_SIZE],rdBuf[BUFFER_SIZE] ;
  922.  
  923.     if (StringLength (new_cal_code) > 12)
  924.         return  VI_ERROR_PARAMETER2;
  925.         
  926.     Fmt (wrtBuf, "%s<:CAL:SEC:CODE %s\r\n", new_cal_code);
  927.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  928.         return hp34401a_status;
  929.     /*  Check the Status Byte of the instrument for proper execution.  */
  930.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  931.         return hp34401a_status;
  932.         
  933.     return hp34401a_status;
  934. }
  935.  
  936. /* ========================================================================= */
  937. /* Function: Calibrate stamp                                                 */
  938. /* Purpose: Allow user to store in nonvolital memory                         */
  939. /* ========================================================================= */
  940. ViStatus _VI_FUNC hp34401a_calStamp (ViSession instrSession, ViChar stamp[])
  941. {
  942.     ViStatus hp34401a_status = VI_SUCCESS;
  943.     ViUInt32 retCnt = 0;
  944.     ViByte  wrtBuf[BUFFER_SIZE],rdBuf[BUFFER_SIZE]  ;
  945.  
  946.     if (StringLength (stamp) > 40)
  947.         return  VI_ERROR_PARAMETER2;
  948.         
  949.     Fmt (wrtBuf, "%s<:CAL:STR \"%s\"\r\n", stamp);
  950.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  951.         return hp34401a_status;
  952.     /*  Check the Status Byte of the instrument for proper execution.  */
  953.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  954.         return hp34401a_status;
  955.         
  956.     return hp34401a_status;
  957. }
  958.  
  959. /* ========================================================================= */
  960. /* Function: Full calibration                                                */
  961. /* Purpose: Making full calibration                                          */
  962. /* ========================================================================= */
  963. ViStatus _VI_FUNC hp34401a_calibrate (ViSession instrSession, ViReal64 cal_val,
  964.                              ViInt16 *cal_code)
  965. {
  966.     ViStatus hp34401a_status = VI_SUCCESS;
  967.     ViUInt32 retCnt = 0;
  968.     ViByte  wrtBuf[BUFFER_SIZE], rdBuf[BUFFER_SIZE]  ;
  969.  
  970.     Fmt (wrtBuf, "%s<:CAL:VAL %f;:CAL?\r\n", cal_val);
  971.     if ((hp34401a_status = viWrite (instrSession, wrtBuf, NumFmtdBytes (),&retCnt)) < 0)
  972.         return hp34401a_status;
  973.     if ((hp34401a_status = viRead (instrSession, rdBuf, MAX_CMD_LENGTH,&retCnt)) < 0)
  974.         return hp34401a_status;
  975.     if (Scan (rdBuf, "%s>%d[b2]", cal_code) != 1) 
  976.         return VI_ERROR_INTERPRETING_RESPONSE;
  977.     /*  Check the Event Status Byte of the instrument for proper execution.  */
  978.     if (hp34401a_checkInstrStatus (instrSession) != 0)
  979.         return hp34401a_status;
  980.         
  981.     return hp34401a_status;
  982. }
  983.  
  984. /*===========================================================================*/
  985. /* Function: Close                                                           */
  986. /* Purpose:  This function closes the instrument.                            */
  987. /*===========================================================================*/
  988. ViStatus _VI_FUNC hp34401a_close (ViSession instrSession)
  989. {
  990.     hp34401a_instrRange instrPtr;
  991.     ViSession rmSession;
  992.     ViStatus hp34401a_status = VI_SUCCESS;
  993.  
  994.     if ((hp34401a_status = viGetAttribute (instrSession, VI_ATTR_RM_SESSION, &rmSession)) < 0)
  995.         return hp34401a_status;
  996.     if ((hp34401a_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  997.         return hp34401a_status;
  998.     
  999.     free (instrPtr);
  1000.     
  1001.     hp34401a_status = viClose (instrSession);
  1002.     viClose (rmSession);
  1003.  
  1004.     return hp34401a_status;
  1005. }
  1006.  
  1007. /*****************************************************************************/
  1008. /*= UTILITY ROUTINES (Non-Exportable Functions) =============================*/
  1009. /*****************************************************************************/
  1010.  
  1011. /*===========================================================================*/
  1012. /* Function: Boolean Value Out Of Range - ViBoolean                          */
  1013. /* Purpose:  This function checks a Boolean to see if it is equal to VI_TRUE */
  1014. /*           or VI_FALSE. If the value is out of range, the return value is  */
  1015. /*           VI_TRUE, otherwise the return value is VI_FALSE.                */
  1016. /*===========================================================================*/
  1017. ViBoolean hp34401a_invalidViBooleanRange (ViBoolean val)
  1018. {
  1019.     return ((val != VI_FALSE && val != VI_TRUE) ? VI_TRUE : VI_FALSE);
  1020. }
  1021.  
  1022. /*===========================================================================*/
  1023. /* Function: Short Signed Integer Value Out Of Range - ViInt16               */
  1024. /* Purpose:  This function checks a short signed integer value to see if it  */  
  1025. /*           lies between a minimum and maximum value.  If the value is out  */
  1026. /*           of range, the return value is VI_TRUE, otherwise the return     */
  1027. /*           value is VI_FALSE.                                              */
  1028. /*===========================================================================*/
  1029. ViBoolean hp34401a_invalidViInt16Range (ViInt16 val, ViInt16 min, ViInt16 max)
  1030. {
  1031.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  1032. }
  1033.  
  1034. /*===========================================================================*/
  1035. /* Function: Long Signed Integer Value Out Of Range - ViInt32                */
  1036. /* Purpose:  This function checks a long signed integer value to see if it   */  
  1037. /*           lies between a minimum and maximum value.  If the value is out  */
  1038. /*           of range,  the return value is VI_TRUE, otherwise the return    */
  1039. /*           value is VI_FALSE.                                              */
  1040. /*===========================================================================*/
  1041. ViBoolean hp34401a_invalidViInt32Range  (ViInt32 val, ViInt32 min, ViInt32 max)
  1042. {
  1043.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  1044. }
  1045.  
  1046. /*===========================================================================*/
  1047. /* Function: Short Unsigned Integer Value Out Of Range - ViUInt16            */
  1048. /* Purpose:  This function checks a short unsigned integer value to see if it*/  
  1049. /*           lies between a minimum and maximum value.  If the value is out  */
  1050. /*           of range,  the return value is VI_TRUE, otherwise the return    */
  1051. /*           value is VI_FALSE.                                              */
  1052. /*===========================================================================*/
  1053. ViBoolean hp34401a_invalidViUInt16Range  (ViUInt16 val, ViUInt16 min, ViUInt16 max)
  1054. {
  1055.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  1056. }
  1057.  
  1058. /*===========================================================================*/
  1059. /* Function: Long Unsigned Integer Value Out Of Range - ViUInt32             */
  1060. /* Purpose:  This function checks a long unsigned integer value to see if it */  
  1061. /*           lies between a minimum and maximum value.  If the value is out  */
  1062. /*           of range,  the return value is VI_TRUE, otherwise the return    */
  1063. /*           value is VI_FALSE.                                              */
  1064. /*===========================================================================*/
  1065. ViBoolean hp34401a_invalidViUInt32Range  (ViUInt32 val, ViUInt32 min, ViUInt32 max)
  1066. {
  1067.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  1068. }
  1069.  
  1070. /*===========================================================================*/
  1071. /* Function: Real (Float) Value Out Of Range - ViReal32                      */
  1072. /* Purpose:  This function checks a real (float) value to see if it lies     */  
  1073. /*           between a minimum and maximum value.  If the value is out of    */
  1074. /*           range, the return value is VI_TRUE, otherwise the return value  */
  1075. /*           is VI_FALSE.                                                    */
  1076. /*===========================================================================*/
  1077. ViBoolean hp34401a_invalidViReal32Range  (ViReal32 val, ViReal32 min, ViReal32 max)
  1078. {
  1079.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  1080. }
  1081.  
  1082. /*===========================================================================*/
  1083. /* Function: Real (Double) Value Out Of Range - ViReal64                     */
  1084. /* Purpose:  This function checks a real (ViReal64) value to see if it lies  */  
  1085. /*           between a minimum and maximum value.  If the value is out of    */
  1086. /*           range, the return value is VI_TRUE, otherwise the return value  */
  1087. /*           is VI_FALSE.                                                    */
  1088. /*===========================================================================*/
  1089. ViBoolean hp34401a_invalidViReal64Range  (ViReal64 val, ViReal64 min, ViReal64 max)
  1090. {
  1091.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  1092. }
  1093.  
  1094. /*===========================================================================*/
  1095. /* Function: Initialize Clean Up                                             */
  1096. /* Purpose:  This function is used only by the hp34401a_init function.  When */
  1097. /*           an error is detected this function is called to close the       */
  1098. /*           open resource manager and instrument object sessions and to     */
  1099. /*           set the instrSession that is returned from hp34401a_init to     */
  1100. /*           VI_NULL.                                                        */
  1101. /*===========================================================================*/
  1102. ViStatus hp34401a_initCleanUp (ViSession openRMSession,
  1103.                     ViPSession openInstrSession, ViStatus currentStatus)
  1104. {
  1105.     viClose (*openInstrSession);
  1106.     viClose (openRMSession);
  1107.     *openInstrSession = VI_NULL;
  1108.     
  1109.     return currentStatus;
  1110. }
  1111.  
  1112. /*===========================================================================*/
  1113. /* Function: Read To File From Instrument                                    */
  1114. /* Purpose:  This function is used to read data from the instrument and      */
  1115. /*           write it to a user specified file.                              */
  1116. /*===========================================================================*/
  1117. ViStatus hp34401a_readToFile (ViSession instrSession, ViString filename,
  1118.                     ViUInt32 readBytes, ViPUInt32 retCount)
  1119. {
  1120.     ViStatus  hp34401a_status = VI_SUCCESS;
  1121.     ViByte    buffer[BUFFER_SIZE];
  1122.     ViUInt32  bytesReadInstr = 0, bytesWrittenFile = 0;
  1123.     FILE     *targetFile;
  1124.  
  1125.     *retCount = 0L;
  1126.     if ((targetFile = fopen (filename, "wb")) == VI_NULL)
  1127.         return VI_ERROR_FILE_OPEN; /* not defined by VTL */
  1128.  
  1129.     for (;;) {
  1130.         if (readBytes > BUFFER_SIZE)
  1131.             hp34401a_status = viRead (instrSession, buffer, BUFFER_SIZE, &bytesReadInstr);
  1132.         else
  1133.             hp34401a_status = viRead (instrSession, buffer, readBytes, &bytesReadInstr);
  1134.  
  1135.         bytesWrittenFile = fwrite (buffer, sizeof (ViByte), (size_t)bytesReadInstr, targetFile);
  1136.         *retCount += bytesWrittenFile;
  1137.         if (bytesWrittenFile < bytesReadInstr)
  1138.             hp34401a_status = VI_ERROR_FILE_WRITE; /* not defined by VTL */
  1139.  
  1140.         if ((readBytes <= BUFFER_SIZE) || (hp34401a_status <= 0) || (hp34401a_status == VI_SUCCESS_TERM_CHAR))
  1141.             break;
  1142.  
  1143.         readBytes -= BUFFER_SIZE;
  1144.     }
  1145.  
  1146.     fclose (targetFile);
  1147.     return hp34401a_status;
  1148. }
  1149.  
  1150. /*===========================================================================*/
  1151. /* Function: Write From File To Instrument                                   */
  1152. /* Purpose:  This function is used to read data from a user specified file   */
  1153. /*           and write it to the instrument.                                 */
  1154. /*===========================================================================*/
  1155. ViStatus hp34401a_writeFromFile (ViSession instrSession, ViString filename,
  1156.                     ViUInt32 writeBytes, ViPUInt32 retCount)
  1157. {
  1158.     ViStatus  hp34401a_status = VI_SUCCESS;
  1159.     ViByte    buffer[BUFFER_SIZE];
  1160.     ViUInt32  bytesRead = 0, bytesWritten = 0;
  1161.     FILE     *sourceFile;
  1162.     ViBoolean sendEnd = VI_FALSE;
  1163.  
  1164.     *retCount = 0L;
  1165.     if ((sourceFile = fopen (filename, "rb")) == VI_NULL)
  1166.         return VI_ERROR_FILE_OPEN; /* not defined by VTL */
  1167.  
  1168.     while (!feof (sourceFile)) {
  1169.         bytesRead = (ViUInt32)fread (buffer, sizeof (ViByte), BUFFER_SIZE, sourceFile);
  1170.         if ((writeBytes > BUFFER_SIZE) && (bytesRead == BUFFER_SIZE)) {
  1171.             viGetAttribute (instrSession, VI_ATTR_SEND_END_EN, &sendEnd);
  1172.             viSetAttribute (instrSession, VI_ATTR_SEND_END_EN, VI_FALSE);
  1173.             hp34401a_status = viWrite (instrSession, buffer, BUFFER_SIZE, &bytesWritten);
  1174.             viSetAttribute (instrSession, VI_ATTR_SEND_END_EN, sendEnd);
  1175.             writeBytes -= BUFFER_SIZE;
  1176.             *retCount += bytesWritten;
  1177.             if (hp34401a_status < 0)
  1178.                 break;
  1179.         }
  1180.         else {
  1181.             hp34401a_status = viWrite (instrSession, buffer, ((bytesRead < writeBytes) ? bytesRead : writeBytes), &bytesWritten);
  1182.             *retCount += bytesWritten;
  1183.             break;
  1184.         }
  1185.     }
  1186.  
  1187.     fclose (sourceFile);
  1188.     return hp34401a_status;
  1189. }
  1190.  
  1191. /* ========================================================================= */
  1192. /*  Function Name:     Check Instrument Status                               */
  1193. /*  Description:       Checks the status of the Instrument                   */
  1194. /*                     and sets hp34401a Error accordingly.                  */
  1195. /*  Return Value:      hp34401a Error (Instrument Driver Status)             */
  1196. /* ========================================================================= */
  1197. ViInt16 hp34401a_checkInstrStatus (ViStatus instrSession)
  1198. {
  1199. ViStatus hp34401a_status = VI_SUCCESS;
  1200. ViUInt32 retCnt = 0;
  1201. ViByte  wrtBuf[BUFFER_SIZE],rdBuf[BUFFER_SIZE];
  1202. ViInt16 event_status;
  1203.  
  1204.     if ((viWrite (instrSession,"*ESR?\r\n",7,&retCnt)) < 0)
  1205.         return hp34401a_status;
  1206.     if ((hp34401a_status = viRead (instrSession,rdBuf,MAX_CMD_LENGTH,&retCnt)) < 0)
  1207.         return hp34401a_status;
  1208.  
  1209.     if (Scan (rdBuf, "%s>%d[b2]", &event_status) != 1)  
  1210.         return VI_ERROR_INTERPRETING_RESPONSE;
  1211.                     
  1212.     return hp34401a_status;
  1213. }
  1214.  
  1215. /* ========================================================================= */
  1216. /*  Function Name: String to Integer                                         */
  1217. /*  Description:   Compares a string to an array of strings and if a match   */
  1218. /*                 is found returns the array index of the match.            */
  1219. /*  Return Value:  Error (Instr. Driver Status)                              */
  1220. /* ========================================================================= */
  1221. ViInt16 hp34401a_stringToInt (ViChar *array_of_strings[],ViInt16 start, ViInt16 stop,
  1222.                                 ViChar *string,ViInt16 * index)
  1223. {
  1224. ViStatus    hp34401a_status = VI_SUCCESS;
  1225.     ViInt16 i;
  1226.     ViInt16 found;
  1227.  
  1228.     hp34401a_status = 0;
  1229.     found = 0;
  1230.     for (i = start; i <= stop && !found; i++)
  1231.         if (!CompareStrings (array_of_strings[i], 0, string, 0, 0))  {
  1232.             *index = i;
  1233.             found = 1;
  1234.         }
  1235.     if (!found)
  1236.         hp34401a_status =  VI_ERROR_INTERPRETING_RESPONSE;
  1237.         
  1238.     return hp34401a_status;
  1239. }
  1240.  
  1241. /*****************************************************************************/
  1242. /*----------- INSERT INSTRUMENT-DEPENDENT UTILITY ROUTINES HERE -------------*/
  1243. /*****************************************************************************/
  1244.  
  1245. /*===========================================================================*/
  1246. /* Function: Default Instrument Setup                                        */
  1247. /* Purpose:  This function sends a default setup to the instrument.  This    */
  1248. /*           function is called by the hp34401a_reset operation and by the   */
  1249. /*           hp34401a_init function if the reset option has not been         */
  1250. /*           selected.  This function is useful for configuring any          */
  1251. /*           instrument settings that are required by the rest of the        */
  1252. /*           instrument driver functions such as turning headers ON or OFF   */
  1253. /*           or using the long or short form for commands, queries, and data.*/                                    
  1254. /*===========================================================================*/
  1255. ViStatus hp34401a_defaultInstrSetup (ViSession instrSession)
  1256. {
  1257.     ViStatus hp34401a_status = VI_SUCCESS;
  1258.     ViUInt32 retCnt = 0;
  1259.     
  1260.     return hp34401a_status;
  1261. }
  1262.  
  1263. /*****************************************************************************/
  1264. /*=== END INSTRUMENT DRIVER SOURCE CODE =====================================*/
  1265. /*****************************************************************************/
  1266.