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

  1. /*****************************************************************************/
  2. /*   Copyright 1996 National Instruments Corporation.  All Rights Reserved.  */
  3. /*****************************************************************************/
  4.  
  5. #include <visa.h>
  6. #include <ansi_c.h>
  7. #include <string.h>
  8. #include <formatio.h>
  9. #include "fl45.h"
  10.  
  11. #define fl45_REVISION     "Rev 1.0, 9/95, CVI 3.1" /*  Instrument driver revision */
  12. #define BUFFER_SIZE         512L         /*  File I/O buffer size       */
  13.  
  14. /*===========================================================================*/
  15. /*= Fluke 45 Digital Multimeter (VISA I/O) ==================================*/
  16. /* LabWindows/CVI 3.1 Instrument Driver                                      */
  17. /* Original Release: September 1995                                          */
  18. /* By: JRO, National Instruments, Austin Texas                               */
  19. /*     PH. (800)433-3488   Fax (512)794-5678                                 */
  20. /*                                                                           */
  21. /* Modification History:                                                     */
  22. /*                                                                           */
  23. /*      June 1995 -  Modified the LabWindows/CVI instrument driver to use    */
  24. /*                   VISA I/O calls.                                         */
  25. /*                                                                           */
  26. /*                   Modified by: JRO, National Instruments, Austin, Texas   */
  27. /*                                                                           */
  28. /*===========================================================================*/
  29.               
  30. /*****************************************************************************/
  31. /*= INSTRUMENT-DEPENDENT COMMAND ARRAYS =====================================*/
  32. /*****************************************************************************/
  33. static ViString primDispFunc[10] = {"AAC","AACDC","ADC","CONT","DIODE","FREQ","OHMS","VAC","VACDC","VDC"};
  34. static ViString secDispFunc[8]  = {"AAC2","ADC2","DIODE2","FREQ2","OHMS2","VAC2","VDC2","CLR2"};
  35. static ViString primDispRange[2] = {"FIXED","AUTO"};
  36. static ViString primDispRate[3] = {"S","M","F"};
  37. static ViString decibel[4] = {"DBCLR","DB; DBREF","DBREF","DBPOWER"};
  38. static ViString minMaxSet[5] = {"MMCLR","MIN","MINSET","MAX","MAXSET"};
  39. static ViString relative[3] = {"RELCLR","REL","RELSET"};
  40.  
  41. /*****************************************************************************/
  42. /*= UTILITY ROUTINE DECLARATIONS (Non-Exportable Functions) =================*/
  43. /*****************************************************************************/
  44. ViBoolean fl45_invalidViBooleanRange (ViBoolean val);
  45. ViBoolean fl45_invalidViInt16Range (ViInt16 val, ViInt16 min, ViInt16 max);
  46. ViBoolean fl45_invalidViInt32Range (ViInt32 val, ViInt32 min, ViInt32 max);
  47. ViBoolean fl45_invalidViUInt16Range (ViUInt16 val, ViUInt16 min, ViUInt16 max);
  48. ViBoolean fl45_invalidViUInt32Range (ViUInt32 val, ViUInt32 min, ViUInt32 max);
  49. ViBoolean fl45_invalidViReal32Range (ViReal32 val, ViReal32 min, ViReal32 max);
  50. ViBoolean fl45_invalidViReal64Range (ViReal64 val, ViReal64 min, ViReal64 max);
  51. ViStatus fl45_initCleanUp (ViSession openRMSession, ViPSession openInstrSession, ViStatus currentStatus);
  52. ViStatus fl45_readToFile (ViSession instrSession, ViString filename, ViUInt32 readBytes, ViPUInt32 retCount);
  53. ViStatus fl45_writeFromFile (ViSession instrSession, ViString filename, ViUInt32 writeBytes, ViPUInt32 retCount);
  54. ViStatus fl45_instrStatus (ViSession instrSession);
  55. ViStatus fl45_defaultInstrSetup (ViSession openInstrSession);
  56.  
  57. /*****************************************************************************/
  58. /*= INSTRUMENT-DEPENDENT STATUS/RANGE STRUCTURE  ============================*/
  59. /*****************************************************************************/
  60. /* fl45_stringValPair is used in the PREFIX_errorMessage function            */
  61. /* fl45_statusDataRanges is used to track session dependent status & ranges  */
  62. /*===========================================================================*/
  63. typedef struct  fl45_stringValPair
  64. {
  65.    ViStatus stringVal;
  66.    ViString stringName;
  67. }   fl45_tStringValPair;
  68.  
  69. struct fl45_statusDataRanges {
  70.     ViInt16 primeDispStatus;
  71.     ViInt16 secDispStatus;
  72.     ViInt16 trigStatus;
  73.     ViChar instrDriverRevision[256];
  74. };
  75.  
  76. typedef struct fl45_statusDataRanges *fl45_instrRange;
  77.  
  78. /*****************************************************************************/
  79. /*====== USER-CALLABLE FUNCTIONS (Exportable Functions) =====================*/
  80. /*****************************************************************************/
  81.  
  82. /*===========================================================================*/
  83. /* Function: Initialize                                                      */
  84. /* Purpose:  This function opens the instrument, queries the instrument for  */
  85. /*           its ID, and initializes the instrument to a known state.        */
  86. /*===========================================================================*/
  87. ViStatus _VI_FUNC fl45_init (ViRsrc resourceName, ViBoolean IDQuery,
  88.                     ViBoolean reset, ViPSession instrSession)
  89. {
  90.     ViStatus fl45_status = VI_SUCCESS;
  91.     ViSession rmSession = 0;
  92.     ViUInt32 retCnt = 0;
  93.     ViByte rdBuffer[BUFFER_SIZE];
  94.                             
  95.     /*- Check input parameter ranges ----------------------------------------*/
  96.     if (fl45_invalidViBooleanRange (IDQuery))
  97.         return VI_ERROR_PARAMETER2;
  98.     if (fl45_invalidViBooleanRange (reset))
  99.         return VI_ERROR_PARAMETER3;
  100.  
  101.     /*- Open instrument session ---------------------------------------------*/
  102.     if ((fl45_status = viOpenDefaultRM (&rmSession)) < 0)
  103.         return fl45_status;
  104.  
  105.     if ((fl45_status = viOpen (rmSession, resourceName, VI_NULL, VI_NULL, instrSession)) < 0) {
  106.         viClose (rmSession);
  107.         return fl45_status;
  108.     }
  109.  
  110.     /*- Configure VISA Formatted I/O ----------------------------------------*/
  111.     if ((fl45_status = viSetAttribute (*instrSession, VI_ATTR_TMO_VALUE, 10000)) < 0)
  112.             return fl45_initCleanUp (rmSession, instrSession, fl45_status);
  113.     if ((fl45_status = viSetBuf (*instrSession, VI_READ_BUF|VI_WRITE_BUF, 4000)) < 0)
  114.             return fl45_initCleanUp (rmSession, instrSession, fl45_status);
  115.     if ((fl45_status = viSetAttribute (*instrSession, VI_ATTR_WR_BUF_OPER_MODE,
  116.                             VI_FLUSH_ON_ACCESS)) < 0)
  117.             return fl45_initCleanUp (rmSession, instrSession, fl45_status);
  118.     if ((fl45_status = viSetAttribute (*instrSession, VI_ATTR_RD_BUF_OPER_MODE,
  119.                             VI_FLUSH_ON_ACCESS)) < 0)
  120.             return fl45_initCleanUp (rmSession, instrSession, fl45_status);
  121.  
  122.     /*- Identification Query ------------------------------------------------*/
  123.     if (IDQuery) {
  124.         if ((fl45_status = viWrite (*instrSession, "*IDN?", 5, &retCnt)) < 0)
  125.             return fl45_initCleanUp (rmSession, instrSession, fl45_status);
  126.         if ((fl45_status = viRead (*instrSession, rdBuffer, BUFFER_SIZE, &retCnt)) < 0)
  127.             return fl45_status;
  128.  
  129.         Scan (rdBuffer, "FLUKE, 45");
  130.         if (NumFmtdBytes () != 9) 
  131.             return fl45_initCleanUp (rmSession, instrSession, VI_ERROR_FAIL_ID_QUERY);
  132.     }
  133.  
  134.     /*- Reset instrument ----------------------------------------------------*/
  135.     if (reset) {
  136.         if ((fl45_status = fl45_reset (*instrSession)) < 0)
  137.             return fl45_initCleanUp (rmSession, instrSession, fl45_status);
  138.     }       
  139.     else  /*- Send Default Instrument Setup ---------------------------------*/
  140.         if ((fl45_status = fl45_defaultInstrSetup (*instrSession)) < 0)
  141.             return fl45_initCleanUp (rmSession, instrSession, fl45_status);
  142.                        
  143.     if (fl45_instrStatus (*instrSession) != VI_SUCCESS)
  144.         return fl45_initCleanUp (rmSession, instrSession, fl45_status); 
  145.         
  146.     return fl45_status;
  147. }
  148.  
  149. /*=========================================================================*/
  150. /* Function: Setup and Read Measurements                                   */
  151. /* Purpose:  This function configures the primary and secondary display.   */
  152. /*=========================================================================*/
  153. ViStatus _VI_FUNC fl45_applicReadMeas (ViSession instrSession, ViBoolean rdOnly, ViInt16 setPrimDisp, ViInt16 setSecDisp, ViPReal64 rdPrimDisp, ViPReal64 rdSecDisp)
  154. {
  155.     ViStatus fl45_status = VI_SUCCESS;
  156.     fl45_instrRange instrPtr;
  157.     
  158.     if (fl45_invalidViBooleanRange (rdOnly))
  159.         return VI_ERROR_PARAMETER2;
  160.     if (fl45_invalidViInt16Range (setPrimDisp, 0, 9))
  161.         return VI_ERROR_PARAMETER3;
  162.     if (fl45_invalidViInt16Range (setSecDisp, 0, 7))
  163.         return VI_ERROR_PARAMETER4;
  164.  
  165.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  166.         return fl45_status;
  167.  
  168.     if (!rdOnly)
  169.         if ((fl45_status = fl45_configMeas (instrSession, setPrimDisp, setSecDisp)) < 0)
  170.             return fl45_status;
  171.     if ((fl45_status = fl45_measPrimDisp (instrSession, VI_OFF, rdPrimDisp)) < 0)
  172.         return fl45_status;
  173.     
  174.     if (instrPtr -> secDispStatus)
  175.         if ((fl45_status = fl45_measSecDisp (instrSession, VI_OFF, rdSecDisp)) < 0)
  176.             return fl45_status;
  177.     
  178.     fl45_status =  fl45_instrStatus (instrSession);
  179.     return fl45_status;
  180. }
  181.  
  182. /*=========================================================================*/
  183. /* Function: Primary and Secondary Display Configuration                   */
  184. /* Purpose:  This function configures the primary and secondary display.   */
  185. /*=========================================================================*/
  186. ViStatus _VI_FUNC fl45_configMeas (ViSession instrSession, ViInt16 func1, ViInt16 func2)
  187. {
  188.     ViStatus fl45_status = VI_SUCCESS;
  189.     fl45_instrRange instrPtr;
  190.     
  191.     if (fl45_invalidViInt16Range (func1, 0, 9))
  192.         return VI_ERROR_PARAMETER2;
  193.     if (fl45_invalidViInt16Range (func2, 0, 7))
  194.         return VI_ERROR_PARAMETER3;
  195.         
  196.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  197.         return fl45_status;
  198.  
  199.     if (((func1 == 1) || (func1 == 8)) && (func2 != 7)) {
  200.         fl45_status = VI_ERROR_CONFIGURE_ERROR;
  201.         return fl45_status;
  202.     }
  203.  
  204.     if ((fl45_status = viPrintf (instrSession, "%s; %s;", primDispFunc[func1], secDispFunc[func2])) < 0)
  205.         return fl45_status;
  206.                      
  207.     instrPtr -> primeDispStatus = func1;
  208.     if (func2 < 7)
  209.         instrPtr -> secDispStatus = 1;
  210.     else
  211.         instrPtr -> secDispStatus = 0;
  212.     
  213.     fl45_status =  fl45_instrStatus (instrSession);
  214.     return fl45_status;
  215. }
  216.  
  217. /*=========================================================================*/
  218. /* Function: Range Configuration                                           */
  219. /* Purpose:  This function configures the autoRange, and sensitivity       */
  220. /*           (if autoRange is off).                                        */
  221. /*=========================================================================*/
  222. ViStatus _VI_FUNC fl45_configRange (ViSession instrSession, ViBoolean autoRange, ViInt16 sens)
  223. {
  224.     ViStatus fl45_status = VI_SUCCESS;
  225.     fl45_instrRange instrPtr;
  226.     ViInt16 n;
  227.     ViUInt32 retCnt = 0;
  228.     ViByte writeBuffer[BUFFER_SIZE];
  229.  
  230.     if (fl45_invalidViBooleanRange (autoRange))
  231.         return VI_ERROR_PARAMETER2;
  232.     if (fl45_invalidViInt16Range (sens, 1, 8))
  233.         return VI_ERROR_PARAMETER3;
  234.         
  235.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  236.         return fl45_status;
  237.     if ((autoRange == 1) && ((instrPtr -> primeDispStatus == 3)
  238.        || (instrPtr -> primeDispStatus == 4))) {
  239.         return VI_ERROR_CONFIGURE_ERROR;
  240.     }
  241.  
  242.     if ((fl45_status = viWrite (instrSession, "MOD?", 4, &retCnt)) < 0)
  243.         return fl45_status;
  244.     if ((fl45_status = viScanf (instrSession, "%hd", &n)) < 0)
  245.         return fl45_status;
  246.     if ((autoRange == 1) && ((n & 0x3B) != 0)) 
  247.         return VI_ERROR_CONFIGURE_RANGE;
  248.     
  249.  
  250.     if (autoRange == 0 && sens < 8)
  251.         Fmt (writeBuffer, "%s<%s;RANGE %d[b2]", primDispRange[autoRange], sens);
  252.     else
  253.         Fmt(writeBuffer,"%s<%s", primDispRange[autoRange]);
  254.  
  255.     if ((fl45_status = viWrite (instrSession, writeBuffer, NumFmtdBytes(), &retCnt)) < 0)
  256.         return fl45_status;
  257.  
  258.     fl45_status = fl45_instrStatus (instrSession);
  259.     return fl45_status;
  260. }
  261.  
  262. /*=========================================================================*/
  263. /* Function: Trigger Configuration                                         */
  264. /* Purpose:  This function configures the measurement rate and trigger.    */
  265. /*=========================================================================*/
  266. ViStatus _VI_FUNC fl45_configTrig (ViSession instrSession, ViInt16 trig, ViInt16 rate)
  267. {
  268.     ViStatus fl45_status = VI_SUCCESS;
  269.     fl45_instrRange instrPtr;
  270.     
  271.     if (fl45_invalidViInt16Range (trig, 1, 5))
  272.         return VI_ERROR_PARAMETER2;
  273.     if (fl45_invalidViInt16Range (rate, 0, 2))
  274.         return VI_ERROR_PARAMETER3;
  275.         
  276.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  277.         return fl45_status;
  278.  
  279.     if ((fl45_status = viPrintf (instrSession, "TRIGGER %hd;RATE %s;", trig, primDispRate[rate])) < 0)
  280.              return fl45_status;
  281.  
  282.     instrPtr -> trigStatus = trig;
  283.     fl45_status =  fl45_instrStatus (instrSession);
  284.     return fl45_status;
  285. }
  286. /*=========================================================================*/
  287. /* Function: Compare                                                       */
  288. /* Purpose:  This function turns the Compare modifier on or off.           */
  289. /*=========================================================================*/
  290. ViStatus _VI_FUNC fl45_configCompare (ViSession instrSession, ViBoolean comp, ViReal64 comp_lo, ViReal64 comp_hi)
  291. {
  292.     ViStatus fl45_status = VI_SUCCESS;
  293.     ViUInt32 retCnt = 0;
  294.     ViByte writeBuffer[BUFFER_SIZE];
  295.  
  296.     if (fl45_invalidViBooleanRange (comp))
  297.         return VI_ERROR_PARAMETER2;
  298.     if (fl45_invalidViReal64Range (comp_lo, -2.0e7, 2.0e7))
  299.         return VI_ERROR_PARAMETER3;
  300.     if (fl45_invalidViReal64Range (comp_hi, -2.0e7, 2.0e7))
  301.         return VI_ERROR_PARAMETER4;
  302.  
  303.     if (comp == 0)
  304.         Fmt (writeBuffer, "%s<COMPCLR");
  305.     else
  306.         Fmt (writeBuffer, "%s<COMP; COMPLO %f; COMPHI %f; HOLD;", comp_lo, comp_hi);
  307.  
  308.     if ((fl45_status = viWrite (instrSession, writeBuffer, NumFmtdBytes(), &retCnt)) < 0)
  309.         return fl45_status;
  310.  
  311.     fl45_status =  fl45_instrStatus (instrSession);
  312.     return fl45_status;
  313. }
  314.  
  315. /*=========================================================================*/
  316. /* Function: Hold                                                          */
  317. /* Purpose:  This function turns the Touch Hold modifier on or off.        */
  318. /*=========================================================================*/
  319. ViStatus _VI_FUNC fl45_configHold (ViSession instrSession, ViBoolean hold, ViInt16 hold_thresh)
  320. {
  321.     ViStatus fl45_status = VI_SUCCESS;
  322.     ViUInt32 retCnt = 0;
  323.     ViByte writeBuffer[BUFFER_SIZE];
  324.  
  325.     if (fl45_invalidViBooleanRange (hold))
  326.         return VI_ERROR_PARAMETER2;
  327.     if (fl45_invalidViInt16Range (hold_thresh, 1, 3))
  328.         return VI_ERROR_PARAMETER3;
  329.  
  330.     if (hold == 0)
  331.         Fmt (writeBuffer, "%s<HOLDCLR");
  332.     else
  333.         Fmt (writeBuffer, "%s<HOLD;HOLDTHRESH %d; HOLD;",hold_thresh);
  334.  
  335.     if ((fl45_status = viWrite (instrSession, writeBuffer, NumFmtdBytes(), &retCnt)) < 0)
  336.         return fl45_status;
  337.  
  338.     fl45_status =  fl45_instrStatus (instrSession);
  339.     return fl45_status;
  340. }
  341.  
  342. /*=========================================================================*/
  343. /* Function: Decibels                                                      */
  344. /* Purpose:  This functions turns the DB modifier (dBm or dB power) on or  */
  345. /*           off.                                                          */
  346. /*=========================================================================*/
  347. ViStatus _VI_FUNC fl45_configDecibel (ViSession instrSession, ViInt16 db, ViInt16 db_ref)
  348. {
  349.     ViStatus fl45_status = VI_SUCCESS;
  350.     fl45_instrRange instrPtr;
  351.     ViUInt32 retCnt = 0;
  352.     ViByte writeBuffer[BUFFER_SIZE];
  353.  
  354.     if (fl45_invalidViInt16Range (db, 0, 2))
  355.         return VI_ERROR_PARAMETER2;
  356.     if (fl45_invalidViInt16Range (db_ref, 1, 21))
  357.         return VI_ERROR_PARAMETER3;
  358.  
  359.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  360.         return fl45_status;
  361.    
  362.     if (db == 0)
  363.         Fmt (writeBuffer, "%s<%s;", decibel[db]);
  364.     else {
  365.         if (instrPtr -> primeDispStatus < 7) 
  366.             return VI_ERROR_CONFIGURE_ERROR;
  367.         
  368.         if ((db == 2) && (db_ref > 4)) 
  369.             return VI_ERROR_CONFIGURE_RANGE;
  370.         
  371.         if (db==1)
  372.             Fmt (writeBuffer, "%s<%s %d;", decibel[db], db_ref);
  373.         else
  374.             Fmt (writeBuffer, "%s<%s %d; %s;", decibel[db], db_ref, decibel[db+1]);
  375.     }
  376.  
  377.     if ((fl45_status = viWrite (instrSession, writeBuffer, NumFmtdBytes(), &retCnt)) < 0)
  378.         return fl45_status;
  379.  
  380.     fl45_status =  fl45_instrStatus (instrSession);
  381.     return fl45_status;
  382. }
  383.  
  384. /*=========================================================================*/
  385. /* Function: Relative                                                      */
  386. /* Purpose:  This function turns the Relative modifier on or off.          */
  387. /*=========================================================================*/
  388. ViStatus _VI_FUNC fl45_configRelative (ViSession instrSession, ViInt16 rel, ViReal64 base_set)
  389. {
  390.     ViStatus fl45_status = VI_SUCCESS;
  391.     ViUInt32 retCnt = 0;
  392.     ViByte writeBuffer[BUFFER_SIZE];
  393.  
  394.     if (fl45_invalidViInt16Range (rel, 0, 2))
  395.         return VI_ERROR_PARAMETER2;
  396.     if (fl45_invalidViReal64Range (base_set, -2e7, 2e7))
  397.         return VI_ERROR_PARAMETER3;
  398.                
  399.     if (rel == 2)
  400.         Fmt(writeBuffer, "%s<%s %f;", relative[rel],base_set);
  401.     else
  402.         Fmt(writeBuffer, "%s<%s;", relative[rel]);
  403.  
  404.     if ((fl45_status = viWrite (instrSession, writeBuffer, NumFmtdBytes(), &retCnt)) < 0)
  405.         return fl45_status;
  406.  
  407.     fl45_status =  fl45_instrStatus (instrSession);
  408.     return fl45_status;
  409. }
  410.  
  411. /*=========================================================================*/
  412. /* Function: Min/Max                                                       */
  413. /* Purpose:  This function turns the MN MX modifier on or off.             */
  414. /*=========================================================================*/
  415. ViStatus _VI_FUNC fl45_configMinMax (ViSession instrSession, ViInt16 min_max, ViReal64 min_set, ViReal64 max_set)
  416. {
  417.     ViStatus fl45_status = VI_SUCCESS;
  418.     ViUInt32 retCnt = 0;
  419.     ViByte writeBuffer[BUFFER_SIZE];
  420.  
  421.     if (fl45_invalidViInt16Range (min_max, 0, 4))
  422.         return VI_ERROR_PARAMETER2;
  423.     if (fl45_invalidViReal64Range (min_set, -2.0e7, 2.0e7))
  424.         return VI_ERROR_PARAMETER3;
  425.     if (fl45_invalidViReal64Range (max_set, -2.0e7, 2.0e7))
  426.         return VI_ERROR_PARAMETER4;
  427.  
  428.     if (min_max == 2)
  429.         Fmt(writeBuffer, "%s<%s %f;",minMaxSet[min_max], min_set);
  430.     else if (min_max == 4)
  431.         Fmt(writeBuffer, "%s<%s %f;",minMaxSet[min_max], max_set);
  432.     else
  433.         Fmt(writeBuffer, "%s<%s;", minMaxSet[min_max]);
  434.  
  435.     if ((fl45_status = viWrite (instrSession, writeBuffer, NumFmtdBytes(), &retCnt)) < 0)
  436.         return fl45_status;
  437.  
  438.     fl45_status =  fl45_instrStatus (instrSession);
  439.     return fl45_status;
  440. }
  441.  
  442. /*=========================================================================*/
  443. /* Function: Trigger                                                       */
  444. /* Purpose:  The trigger function executes a trigger.                      */
  445. /*=========================================================================*/
  446. ViStatus _VI_FUNC fl45_trigger (ViSession instrSession)
  447. {
  448.     ViStatus fl45_status = VI_SUCCESS;
  449.     fl45_instrRange instrPtr;
  450.     ViUInt32 retCnt = 0;
  451.     
  452.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  453.         return fl45_status;
  454.  
  455.     if (instrPtr -> trigStatus > 1)
  456.         if ((fl45_status = viWrite (instrSession, "*TRG;", 5, &retCnt)) < 0)
  457.             return fl45_status;
  458.  
  459.     fl45_status =  fl45_instrStatus (instrSession);
  460.     return fl45_status;
  461. }
  462.  
  463. /*=========================================================================*/
  464. /* Function: fl45_Compare                                                  */
  465. /* Purpose:  The Compare function when executed will display if the        */
  466. /*           measurement is within the values defined in the               */
  467. /*           fl45_Config_compare.  The function checks to see if the       */
  468. /*           Compare function has been executed.                           */
  469. /*=========================================================================*/
  470. ViStatus _VI_FUNC fl45_measCompare (ViSession instrSession, ViPChar charOutput, ViPInt16 intOutput)
  471. {
  472.     ViStatus fl45_status = VI_SUCCESS;
  473.     ViUInt32 retCnt = 0;
  474.     ViUInt16 n = 0;
  475.     ViByte rdBuffer[BUFFER_SIZE];
  476.               
  477.     FillBytes (charOutput, 0, 8, 0);
  478.     
  479.     if ((fl45_status = viWrite (instrSession, "MOD?", 4, &retCnt)) < 0)
  480.         return fl45_status;
  481.     if ((fl45_status = viScanf (instrSession, "%hd", &n)) < 0)
  482.         return fl45_status;
  483.     
  484.     if ((n & 64) != 64) 
  485.         return VI_ERROR_CONFIGURE_COMPARE;
  486.     
  487.     if ((fl45_status = viWrite (instrSession, "COMP?", 5, &retCnt)) < 0)
  488.         return fl45_status;
  489.     if ((fl45_status = viRead (instrSession, rdBuffer, BUFFER_SIZE, &retCnt)) < 0)
  490.         return fl45_status;
  491.     if (Scan (rdBuffer, "%s>%s[xt10]", charOutput) != 1) 
  492.         return VI_ERROR_INTERPRETING_RESPONSE;
  493.  
  494.     switch (charOutput[0]) {
  495.         case 'H': *intOutput = 1;
  496.                   break;
  497.         case 'P': *intOutput = 0;
  498.                   break;
  499.         case 'L': *intOutput = -1;
  500.                   break;
  501.         default : *intOutput = -999;
  502.                   break;
  503.     }
  504.  
  505.     fl45_status =  fl45_instrStatus (instrSession);
  506.     return fl45_status;
  507. }
  508.  
  509. /*=========================================================================*/
  510. /* Function: Primary Display                                               */
  511. /* Purpose:  This function reads the data from the Primary Display.        */
  512. /*=========================================================================*/
  513. ViStatus _VI_FUNC fl45_measPrimDisp (ViSession instrSession, ViBoolean wait, ViPReal64 ch_1)
  514. {
  515.     ViStatus fl45_status = VI_SUCCESS;
  516.     fl45_instrRange instrPtr;
  517.     ViUInt32 retCnt = 0;
  518.     ViUInt16 status = 0, done = 0;
  519.  
  520.     if (fl45_invalidViBooleanRange (wait))
  521.         return VI_ERROR_PARAMETER2;
  522.     
  523.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  524.         return fl45_status;
  525.                
  526.     if (instrPtr -> trigStatus > 1) {
  527.         if (wait == 0) {
  528.             if ((fl45_status = viWrite (instrSession, "VAL1?", 5, &retCnt)) < 0)
  529.                 return fl45_status;
  530.         }
  531.         else {
  532.             if ((fl45_status = viWrite (instrSession, "MEAS1?", 6, &retCnt)) < 0)
  533.                 return fl45_status;
  534.             done = 0;
  535.             while (!done) {
  536.                 if ((fl45_status = viReadSTB (instrSession, &status)) < 0)
  537.                     return fl45_status;
  538.                 if ((status & 0x10) == 0x10)
  539.                     done = 1;
  540.                 if (fl45_status != VI_SUCCESS)
  541.                     return fl45_status;
  542.             }
  543.         }
  544.     }
  545.     else
  546.         if ((fl45_status = viWrite (instrSession, "VAL1?", 5, &retCnt)) < 0)
  547.             return fl45_status;
  548.  
  549.     if ((fl45_status = viScanf (instrSession, "%lf", ch_1)) < 0)
  550.         return fl45_status;
  551.  
  552.     fl45_status =  fl45_instrStatus (instrSession);
  553.     return fl45_status;
  554. }
  555.  
  556. /*=========================================================================*/
  557. /* Function: Secondary Display                                             */
  558. /* Purpose:  This function reads the data from the Secondary Display.      */
  559. /*=========================================================================*/
  560. ViStatus _VI_FUNC fl45_measSecDisp (ViSession instrSession, ViBoolean wait, ViPReal64 ch_2)
  561. {
  562.     ViStatus fl45_status = VI_SUCCESS;
  563.     fl45_instrRange instrPtr;
  564.     ViUInt32 retCnt = 0;
  565.     ViUInt16 status = 0, done = 0;
  566.  
  567.     if (fl45_invalidViBooleanRange (wait))
  568.         return VI_ERROR_PARAMETER2;
  569.     
  570.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  571.         return fl45_status;
  572.                
  573.     if (instrPtr -> trigStatus > 1) {
  574.         if (wait == 0) {
  575.             if ((fl45_status = viWrite (instrSession, "VAL2?", 5, &retCnt)) < 0)
  576.                 return fl45_status;
  577.         }
  578.         else {
  579.             if ((fl45_status = viWrite (instrSession, "MEAS2?", 6, &retCnt)) < 0)
  580.                 return fl45_status;
  581.             done = 0;
  582.             while (!done) {
  583.                 if ((fl45_status = viReadSTB (instrSession, &status)) < 0)
  584.                     return fl45_status;
  585.                 if ((status & 0x10) == 0x10)
  586.                     done = 1;
  587.                 if (fl45_status != VI_SUCCESS)
  588.                     return fl45_status;
  589.             }
  590.         }
  591.     }
  592.     else
  593.         if ((fl45_status = viWrite (instrSession, "VAL2?", 5, &retCnt)) < 0)
  594.             return fl45_status;
  595.  
  596.     if ((fl45_status = viScanf (instrSession, "%lf", ch_2)) < 0)
  597.         return fl45_status;
  598.  
  599.     fl45_status =  fl45_instrStatus (instrSession);
  600.     return fl45_status;
  601. }
  602.  
  603. /*****************************************************************************/
  604. /*-------- INSERT USER-CALLABLE INSTRUMENT-DEPENDENT ROUTINES HERE ----------*/
  605. /*****************************************************************************/
  606.            
  607. /*===========================================================================*/
  608. /* Function: Write To Instrument                                             */
  609. /* Purpose:  This function writes a command string to the instrument.        */
  610. /*===========================================================================*/
  611. ViStatus _VI_FUNC fl45_writeInstrData (ViSession instrSession, ViString writeBuffer)
  612. {
  613.     ViStatus fl45_status = VI_SUCCESS;
  614.     
  615.     if ((fl45_status = viPrintf (instrSession, "%s", writeBuffer)) < 0)
  616.         return fl45_status;
  617.  
  618.     return fl45_status;
  619. }
  620.  
  621. /*===========================================================================*/
  622. /* Function: Read Instrument Buffer                                          */
  623. /* Purpose:  This function reads the output buffer of the instrument.        */
  624. /*===========================================================================*/
  625. ViStatus _VI_FUNC fl45_readInstrData (ViSession instrSession, ViInt16 numBytes,
  626.                     ViChar rdBuf[], ViPInt32 bytesRead)
  627. {
  628.     ViStatus fl45_status = VI_SUCCESS;
  629.     *bytesRead = 0L;
  630.         
  631.     if ((fl45_status = viRead (instrSession, rdBuf, numBytes, bytesRead)) < 0)
  632.         return fl45_status;
  633.  
  634.     return fl45_status;
  635. }
  636.  
  637. /*===========================================================================*/
  638. /* Function: Reset                                                           */
  639. /* Purpose:  This function resets the instrument.  If the reset function     */
  640. /*           is not supported by the instrument, this function returns       */
  641. /*           the warning VI_WARN_NSUP_RESET.                                 */
  642. /*===========================================================================*/
  643. ViStatus _VI_FUNC fl45_reset (ViSession instrSession)
  644. {
  645.     ViUInt32 retCnt = 0;
  646.     ViStatus fl45_status = VI_SUCCESS;
  647.  
  648.     /*  Initialize the instrument to a known state.  */
  649.     if ((fl45_status = viWrite (instrSession, "*RST", 4, &retCnt)) < 0)
  650.         return fl45_status;
  651.  
  652.     if ((fl45_status = fl45_defaultInstrSetup (instrSession)) < 0)  
  653.         return fl45_status;
  654.         
  655.     return fl45_status;
  656. }
  657.  
  658. /*===========================================================================*/
  659. /* Function: Self-Test                                                       */
  660. /* Purpose:  This function executes the instrument self-test and returns     */
  661. /*           the result. If the self test function is not supported by the   */
  662. /*           instrument, this function returns the warning                   */
  663. /*           VI_WARN_NSUP_SELF_TEST.                                         */
  664. /*===========================================================================*/
  665. ViStatus _VI_FUNC fl45_selfTest (ViSession instrSession, ViPInt16 testResult,
  666.                     ViChar testMessage[])
  667. {
  668.     ViUInt16 status = 0, done = 0;
  669.     ViUInt32 retCnt = 0;
  670.     ViStatus fl45_status = VI_SUCCESS;
  671.  
  672.     if ((fl45_status = viWrite (instrSession, "*TST?", 5, &retCnt)) < 0)
  673.         return fl45_status;
  674.    
  675.     done = 0;
  676.     while (done == 0) {
  677.         fl45_status = viReadSTB (instrSession, &status);
  678.         if ((status & 0x10) == 0x10)
  679.              done = 1;
  680.         if (fl45_status != VI_SUCCESS)
  681.             return fl45_status;
  682.     }
  683.     
  684.     if ((fl45_status = viScanf (instrSession, "%hd", testResult)) < 0)
  685.         return fl45_status;
  686.     if (Scan (testResult, "%d[b2]>%s", testMessage) != 1)
  687.         fl45_status = VI_ERROR_INTERPRETING_RESPONSE;
  688.     
  689.     return fl45_status;
  690. }
  691.  
  692. /*===========================================================================*/
  693. /* Function: Error Query                                                     */
  694. /* Purpose:  This function queries the instrument error queue, and returns   */
  695. /*           the result. If the error query function is not supported by the */
  696. /*           instrument, this function returns the warning                   */
  697. /*           VI_WARN_NSUP_ERROR_QUERY.                                       */
  698. /*===========================================================================*/
  699. ViStatus _VI_FUNC fl45_errorQuery (ViSession instrSession, ViPInt32 errCode,
  700.                     ViChar errMessage[])
  701. {
  702.     ViUInt32 retCnt = 0;
  703.     ViStatus fl45_status = VI_SUCCESS;
  704.  
  705.     fl45_status = VI_WARN_NSUP_ERROR_QUERY;                          
  706.  
  707.     return fl45_status;
  708. }
  709.  
  710. /*===========================================================================*/
  711. /* Function: Error Message                                                   */
  712. /* Purpose:  This function translates the error return value from the        */
  713. /*           instrument driver into a user-readable string.                  */
  714. /*===========================================================================*/
  715. ViStatus _VI_FUNC fl45_errorMessage (ViSession instrSession, ViStatus errorCode,
  716.                     ViChar errMessage[])
  717. {
  718.     ViStatus fl45_status = VI_SUCCESS;
  719.     ViInt16 i;
  720.     static fl45_tStringValPair statusDescArray[] = {
  721.         {VI_WARN_NSUP_ID_QUERY,     "WARNING: ID Query not supported"},
  722.         {VI_WARN_NSUP_RESET,        "WARNING: Reset not supported"},
  723.         {VI_WARN_NSUP_SELF_TEST,    "WARNING: Self-test not supported"},
  724.         {VI_WARN_NSUP_ERROR_QUERY,  "WARNING: Error Query not supported"},     
  725.         {VI_WARN_NSUP_REV_QUERY,    "WARNING: Revision Query not supported"},
  726.         {VI_ERROR_PARAMETER1,   "ERROR: Parameter 1 out of range"},
  727.         {VI_ERROR_PARAMETER2,   "ERROR: Parameter 2 out of range"},
  728.         {VI_ERROR_PARAMETER3,   "ERROR: Parameter 3 out of range"},
  729.         {VI_ERROR_PARAMETER4,   "ERROR: Parameter 4 out of range"},
  730.         {VI_ERROR_PARAMETER5,   "ERROR: Parameter 5 out of range"},
  731.         {VI_ERROR_PARAMETER6,   "ERROR: Parameter 6 out of range"},
  732.         {VI_ERROR_PARAMETER7,   "ERROR: Parameter 7 out of range"},
  733.         {VI_ERROR_PARAMETER8,   "ERROR: Parameter 8 out of range"},
  734.         {VI_ERROR_FAIL_ID_QUERY,"ERROR: Identification query failed"},
  735.         {VI_ERROR_INV_RESPONSE, "ERROR: Interpreting instrument response"},
  736.         {VI_ERROR_FILE_OPEN,    "ERROR: Opening the specified file"},
  737.         {VI_ERROR_FILE_WRITE,   "ERROR: Writing to the specified file"},
  738.         {VI_ERROR_INTERPRETING_RESPONSE, "ERROR: Interpreting the instrument's response"},
  739.                 
  740.         /*=CHANGE:=============================================================*/
  741.         /* Insert instrument-specific error codes here.  Example:              */
  742.         /*                                                                     */
  743.         /*  {INSTRUMENT_SPECIFIC_ERROR, "ERROR: Instrument specific error"},   */
  744.         /*                                                                     */
  745.         /*=====================================================================*/
  746.  
  747.         {VI_NULL, VI_NULL}
  748.     };
  749.  
  750.     fl45_status = viStatusDesc (instrSession, errorCode, errMessage);
  751.     if (fl45_status == VI_WARN_UNKNOWN_STATUS) {
  752.         for (i=0; statusDescArray[i].stringName; i++) {
  753.             if (statusDescArray[i].stringVal == errorCode) {
  754.                 strcpy (errMessage, statusDescArray[i].stringName);
  755.                 return (VI_SUCCESS);
  756.             }
  757.         }
  758.         sprintf (errMessage, "Unknown Error 0x%08lX", errorCode);
  759.         return (VI_WARN_UNKNOWN_STATUS);
  760.     }
  761.     
  762.     fl45_status = VI_SUCCESS;
  763.     return fl45_status;
  764. }
  765.  
  766. /*===========================================================================*/
  767. /* Function: Revision Query                                                  */
  768. /* Purpose:  This function returns the driver and instrument revisions.      */
  769. /*           If the revision query function is not supported by the          */ 
  770. /*           instrument, this function returns the warning                   */
  771. /*           VI_WARN_NSUP_REV_QUERY.                                         */
  772. /*===========================================================================*/
  773. ViStatus _VI_FUNC fl45_revisionQuery (ViSession instrSession,
  774.                     ViChar driverRev[], ViChar instrRev[])
  775. {
  776.     ViUInt32 retCnt = 0;
  777.     fl45_instrRange instrPtr;
  778.     ViStatus fl45_status = VI_SUCCESS;
  779.     
  780.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  781.         return fl45_status;
  782.         
  783.     if ((fl45_status = viWrite (instrSession, "*IDN?", 5, &retCnt)) < 0)
  784.         return fl45_status;
  785.  
  786.     if ((fl45_status = viScanf (instrSession, "%*[^,],%*[^,],%*[^,], %[^\n]", instrRev)) < 0)
  787.         return fl45_status;
  788.                   
  789.     strcpy (driverRev, instrPtr -> instrDriverRevision);
  790.     
  791.     return fl45_status;
  792. }
  793.  
  794. /*===========================================================================*/
  795. /* Function: Close                                                           */
  796. /* Purpose:  This function closes the instrument.                            */
  797. /*===========================================================================*/
  798. ViStatus _VI_FUNC fl45_close (ViSession instrSession)
  799. {
  800.     fl45_instrRange instrPtr;
  801.     ViSession rmSession;
  802.     ViStatus fl45_status = VI_SUCCESS;
  803.  
  804.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_RM_SESSION, &rmSession)) < 0)
  805.         return fl45_status;
  806.     if ((fl45_status = viGetAttribute (instrSession, VI_ATTR_USER_DATA, &instrPtr)) < 0)
  807.         return fl45_status;
  808.     
  809.     free (instrPtr);
  810.     
  811.     fl45_status = viClose (instrSession);
  812.     viClose (rmSession);
  813.  
  814.     return fl45_status;
  815. }
  816.  
  817. /*****************************************************************************/
  818. /*= UTILITY ROUTINES (Non-Exportable Functions) =============================*/
  819. /*****************************************************************************/
  820.  
  821. /*===========================================================================*/
  822. /* Function: Boolean Value Out Of Range - ViBoolean                          */
  823. /* Purpose:  This function checks a Boolean to see if it is equal to VI_TRUE */
  824. /*           or VI_FALSE. If the value is out of range, the return value is  */
  825. /*           VI_TRUE, otherwise the return value is VI_FALSE.                */
  826. /*===========================================================================*/
  827. ViBoolean fl45_invalidViBooleanRange (ViBoolean val)
  828. {
  829.     return ((val != VI_FALSE && val != VI_TRUE) ? VI_TRUE : VI_FALSE);
  830. }
  831.  
  832. /*===========================================================================*/
  833. /* Function: Short Signed Integer Value Out Of Range - ViInt16               */
  834. /* Purpose:  This function checks a short signed integer value to see if it  */  
  835. /*           lies between a minimum and maximum value.  If the value is out  */
  836. /*           of range,  the return value is VI_TRUE, otherwise the return    */
  837. /*           value is VI_FALSE.                                              */
  838. /*===========================================================================*/
  839. ViBoolean fl45_invalidViInt16Range (ViInt16 val, ViInt16 min, ViInt16 max)
  840. {
  841.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  842. }
  843.  
  844. /*===========================================================================*/
  845. /* Function: Long Signed Integer Value Out Of Range - ViInt32                */
  846. /* Purpose:  This function checks a long signed integer value to see if it   */  
  847. /*           lies between a minimum and maximum value.  If the value is out  */
  848. /*           of range, the return value is VI_TRUE, otherwise the return     */
  849. /*           value is VI_FALSE.                                              */
  850. /*===========================================================================*/
  851. ViBoolean fl45_invalidViInt32Range  (ViInt32 val, ViInt32 min, ViInt32 max)
  852. {
  853.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  854. }
  855.  
  856. /*===========================================================================*/
  857. /* Function: Short Unsigned Integer Value Out Of Range - ViUInt16            */
  858. /* Purpose:  This function checks a short unsigned integer value to see if it*/
  859. /*           lies between a minimum and maximum value.  If the value is out  */
  860. /*           of range,  the return value is VI_TRUE, otherwise the return    */
  861. /*           value is VI_FALSE.                                              */
  862. /*===========================================================================*/
  863. ViBoolean fl45_invalidViUInt16Range  (ViUInt16 val, ViUInt16 min, ViUInt16 max)
  864. {
  865.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  866. }
  867.  
  868. /*===========================================================================*/
  869. /* Function: Long Unsigned Integer Value Out Of Range - ViUInt32             */
  870. /* Purpose:  This function checks a long unsigned integer value to see if it */  
  871. /*           lies between a minimum and maximum value.  If the value is out  */
  872. /*           of range,  the return value is VI_TRUE, otherwise the return    */
  873. /*           value is VI_FALSE.                                              */
  874. /*===========================================================================*/
  875. ViBoolean fl45_invalidViUInt32Range  (ViUInt32 val, ViUInt32 min, ViUInt32 max)
  876. {
  877.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  878. }
  879.  
  880. /*===========================================================================*/
  881. /* Function: Real (Float) Value Out Of Range - ViReal32                      */
  882. /* Purpose:  This function checks a real (float) value to see if it lies     */  
  883. /*           between a minimum and maximum value.  If the value is out of    */
  884. /*           range, the return value is VI_TRUE, otherwise the return value  */
  885. /*           is VI_FALSE.                                                    */
  886. /*===========================================================================*/
  887. ViBoolean fl45_invalidViReal32Range  (ViReal32 val, ViReal32 min, ViReal32 max)
  888. {
  889.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  890. }
  891.  
  892. /*===========================================================================*/
  893. /* Function: Real (Double) Value Out Of Range - ViReal64                     */
  894. /* Purpose:  This function checks a real (double) value to see if it lies    */  
  895. /*           between a minimum and maximum value.  If the value is out of    */
  896. /*           range, the return value is VI_TRUE, otherwise the return value  */
  897. /*           is VI_FALSE.                                                    */
  898. /*===========================================================================*/
  899. ViBoolean fl45_invalidViReal64Range  (ViReal64 val, ViReal64 min, ViReal64 max)
  900. {
  901.     return ((val < min || val > max) ? VI_TRUE : VI_FALSE);
  902. }
  903.  
  904. /*===========================================================================*/
  905. /* Function: Initialize Clean Up                                             */
  906. /* Purpose:  This function is used only by the fl45_init function.  When     */
  907. /*           an error is detected this function is called to close the       */
  908. /*           open resource manager and instrument object sessions and to     */
  909. /*           set the instrSession that is returned from fl45_init to         */
  910. /*           VI_NULL.                                                        */
  911. /*===========================================================================*/
  912. ViStatus fl45_initCleanUp (ViSession openRMSession,
  913.                     ViPSession openInstrSession, ViStatus currentStatus)
  914. {
  915.     viClose (*openInstrSession);
  916.     viClose (openRMSession);
  917.     *openInstrSession = VI_NULL;
  918.     
  919.     return currentStatus;
  920. }
  921.  
  922. /*===========================================================================*/
  923. /* Function: Read To File From Instrument                                    */
  924. /* Purpose:  This function is used to read data from the instrument and      */
  925. /*           write it to a user specified file.                              */
  926. /*===========================================================================*/
  927. ViStatus fl45_readToFile (ViSession instrSession, ViString filename,
  928.                     ViUInt32 readBytes, ViPUInt32 retCount)
  929. {
  930.     ViStatus  fl45_status = VI_SUCCESS;
  931.     ViByte    buffer[BUFFER_SIZE];
  932.     ViUInt32  bytesReadInstr = 0, bytesWrittenFile = 0;
  933.     FILE     *targetFile;
  934.  
  935.     *retCount = 0L;
  936.     if ((targetFile = fopen (filename, "wb")) == VI_NULL)
  937.         return VI_ERROR_FILE_OPEN; /* not defined by VTL */
  938.  
  939.     for (;;) {
  940.         if (readBytes > BUFFER_SIZE)
  941.             fl45_status = viRead (instrSession, buffer, BUFFER_SIZE, &bytesReadInstr);
  942.         else
  943.             fl45_status = viRead (instrSession, buffer, readBytes, &bytesReadInstr);
  944.  
  945.         bytesWrittenFile = fwrite (buffer, sizeof (ViByte), (size_t)bytesReadInstr, targetFile);
  946.         *retCount += bytesWrittenFile;
  947.         if (bytesWrittenFile < bytesReadInstr)
  948.             fl45_status = VI_ERROR_FILE_WRITE; /* not defined by VTL */
  949.  
  950.         if ((readBytes <= BUFFER_SIZE) || (fl45_status <= 0) || (fl45_status == VI_SUCCESS_TERM_CHAR))
  951.             break;
  952.  
  953.         readBytes -= BUFFER_SIZE;
  954.     }
  955.  
  956.     fclose (targetFile);
  957.     return fl45_status;
  958. }
  959.  
  960. /*===========================================================================*/
  961. /* Function: Write From File To Instrument                                   */
  962. /* Purpose:  This function is used to read data from a user specified file   */
  963. /*           and write it to the instrument.                                 */
  964. /*===========================================================================*/
  965. ViStatus fl45_writeFromFile (ViSession instrSession, ViString filename,
  966.                     ViUInt32 writeBytes, ViPUInt32 retCount)
  967. {
  968.     ViStatus  fl45_status = VI_SUCCESS;
  969.     ViByte    buffer[BUFFER_SIZE];
  970.     ViUInt32  bytesRead = 0, bytesWritten = 0;
  971.     FILE     *sourceFile;
  972.     ViBoolean sendEnd = VI_FALSE;
  973.  
  974.     *retCount = 0L;
  975.     if ((sourceFile = fopen (filename, "rb")) == VI_NULL)
  976.         return VI_ERROR_FILE_OPEN; /* not defined by VTL */
  977.  
  978.     while (!feof (sourceFile)) {
  979.         bytesRead = (ViUInt32)fread (buffer, sizeof (ViByte), BUFFER_SIZE, sourceFile);
  980.         if ((writeBytes > BUFFER_SIZE) && (bytesRead == BUFFER_SIZE)) {
  981.             viGetAttribute (instrSession, VI_ATTR_SEND_END_EN, &sendEnd);
  982.             viSetAttribute (instrSession, VI_ATTR_SEND_END_EN, VI_FALSE);
  983.             fl45_status = viWrite (instrSession, buffer, BUFFER_SIZE, &bytesWritten);
  984.             viSetAttribute (instrSession, VI_ATTR_SEND_END_EN, sendEnd);
  985.             writeBytes -= BUFFER_SIZE;
  986.             *retCount += bytesWritten;
  987.             if (fl45_status < 0)
  988.                 break;
  989.         }
  990.         else {
  991.             fl45_status = viWrite (instrSession, buffer, ((bytesRead < writeBytes) ? bytesRead : writeBytes), &bytesWritten);
  992.             *retCount += bytesWritten;
  993.             break;
  994.         }
  995.     }
  996.  
  997.     fclose (sourceFile);
  998.     return fl45_status;
  999. }
  1000.  
  1001. /*===========================================================================*/
  1002. /* Function: Status                                                          */
  1003. /* Purpose:  This function checks the event status register.                 */
  1004. /*===========================================================================*/
  1005. ViStatus fl45_instrStatus (ViSession instrSession)
  1006. {
  1007.     ViStatus fl45_status = VI_SUCCESS;
  1008.     ViUInt32 retCnt = 0;
  1009.     ViInt16 esr = 0;
  1010.  
  1011.     if ((fl45_status = viWrite (instrSession, "*ESR?;", 6, &retCnt)) < 0)
  1012.         return fl45_status;
  1013.  
  1014.     if ((fl45_status = viScanf (instrSession, "%hd", &esr)) < 0)
  1015.         return fl45_status;
  1016.  
  1017.     if ((esr & 0x10) == 0x10)
  1018.        fl45_status = VI_ERROR_INSTRUMENT_ERROR;
  1019.     else
  1020.        fl45_status = VI_SUCCESS;
  1021.  
  1022.     return fl45_status;
  1023. }
  1024.  
  1025. /*****************************************************************************/
  1026. /*----------- INSERT INSTRUMENT-DEPENDENT UTILITY ROUTINES HERE -------------*/
  1027. /*****************************************************************************/
  1028.  
  1029. /*===========================================================================*/
  1030. /* Function: Default Instrument Setup                                        */
  1031. /* Purpose:  This function sends a default setup to the instrument.  This    */
  1032. /*           function is called by the fl45_reset operation and by the       */
  1033. /*           fl45_init function if the reset option has not been selected.   */
  1034. /*           This function is useful for configuring any instrument settings */
  1035. /*           that are required by the rest of the instrument driver          */
  1036. /*           functions such as turning headers ON or OFF or using the long   */
  1037. /*           or short form for commands, queries, and data.                  */                                    
  1038. /*===========================================================================*/
  1039. ViStatus fl45_defaultInstrSetup (ViSession instrSession)
  1040. {
  1041.     ViStatus fl45_status = VI_SUCCESS;
  1042.     ViUInt32 retCnt = 0;
  1043.     fl45_instrRange instrPtr;
  1044.  
  1045.     instrPtr = malloc (sizeof (struct fl45_statusDataRanges));
  1046.  
  1047.     instrPtr -> primeDispStatus     = 9;
  1048.     instrPtr -> secDispStatus       = 0;
  1049.     instrPtr -> trigStatus          = 1;
  1050.     strcpy (instrPtr -> instrDriverRevision, fl45_REVISION);
  1051.  
  1052.     if (viSetAttribute (instrSession, VI_ATTR_USER_DATA, (ViUInt32)instrPtr) != 0)
  1053.         return fl45_status;                                       
  1054.                  
  1055.     if ((fl45_status = viWrite (instrSession, "*CLS;*ESE 63", 12, &retCnt)) < 0)
  1056.         return fl45_status;
  1057.  
  1058.     return fl45_status;
  1059. }
  1060.  
  1061. /*****************************************************************************/
  1062. /*=== END INSTRUMENT DRIVER SOURCE CODE =====================================*/
  1063. /*****************************************************************************/
  1064.