#include #include #include #include #include "lc8901a.h" #define BUFFER_SIZE 512L /* File I/O buffer size */ /*===========================================================================*/ /*= Lecroy 8901a GPIB Interface =============================================*/ /* LabWindows/CVI 5.0 Instrument Driver */ /* Original Release: */ /* By: Kamran Shah, National Instruments */ /* PH. (512) 683-8248 Fax (512) 683-5678 */ /* */ /* Modification History: None */ /*===========================================================================*/ /*****************************************************************************/ /*= INSTRUMENT-DEPENDENT STATUS/RANGE STRUCTURE ============================*/ /*****************************************************************************/ /* lc8901a_stringValPair is used in the lc8901a_errorMessage function */ /* lc8901a_statusDataRanges is used to track session dependent status & ranges*/ /*===========================================================================*/ typedef struct lc8901a_stringValPair { ViStatus stringVal; ViString stringName; } lc8901a_tStringValPair; struct lc8901a_statusDataRanges { ViInt16 triggerMode; ViInt16 val2; ViInt16 val3; ViChar instrDriverRevision[256]; }; typedef struct lc8901a_statusDataRanges *lc8901a_instrRange; /*****************************************************************************/ /*= UTILITY ROUTINE DECLARATIONS (Non-Exportable Functions) =================*/ /*****************************************************************************/ ViBoolean lc8901a_invalidViBooleanRange (ViBoolean val); ViBoolean lc8901a_invalidViInt16Range (ViInt16 val, ViInt16 min, ViInt16 max); ViBoolean lc8901a_invalidViInt32Range (ViInt32 val, ViInt32 min, ViInt32 max); ViBoolean lc8901a_invalidViUInt8Range (ViUInt8 val, ViUInt8 min, ViUInt8 max); ViBoolean lc8901a_invalidViUInt16Range (ViUInt16 val, ViUInt16 min, ViUInt16 max); ViBoolean lc8901a_invalidViUInt32Range (ViUInt32 val, ViUInt32 min, ViUInt32 max); ViBoolean lc8901a_invalidViReal32Range (ViReal32 val, ViReal32 min, ViReal32 max); ViBoolean lc8901a_invalidViReal64Range (ViReal64 val, ViReal64 min, ViReal64 max); ViStatus lc8901a_waitOnVisaEvent (ViSession instrSession, ViEventType eventTypeIn, ViUInt32 tmoIn, ViPUInt16 STB); ViStatus lc8901a_initCleanUp (ViSession openRMSession, ViPSession openInstrSession, ViStatus currentStatus); /*===========================================================================*/ /* Function: Initialize */ /* Purpose: This function opens the instrument. */ /*===========================================================================*/ ViStatus _VI_FUNC lc8901a_init (ViRsrc resourceName, ViInt16 transferMode, ViInt16 dataWord, ViPSession instrSession) { ViStatus lc8901a_status = VI_SUCCESS; ViSession rmSession = 0; ViUInt32 retCnt = 0; ViByte rdBuffer[BUFFER_SIZE]; /*- Open instrument session ---------------------------------------------*/ if ((lc8901a_status = viOpenDefaultRM (&rmSession)) < 0) return lc8901a_status; if ((lc8901a_status = viOpen (rmSession, resourceName, VI_NULL, VI_NULL, instrSession)) < 0) { viClose (rmSession); return lc8901a_status; } /*- Configure VISA Formatted I/O ----------------------------------------*/ if ((lc8901a_status = viSetAttribute (*instrSession, VI_ATTR_TMO_VALUE, 10000)) < 0) return lc8901a_initCleanUp (rmSession, instrSession, lc8901a_status); if ((lc8901a_status = viSetBuf (*instrSession, VI_READ_BUF|VI_WRITE_BUF, 4000)) < 0) return lc8901a_initCleanUp (rmSession, instrSession, lc8901a_status); if ((lc8901a_status = viSetAttribute (*instrSession, VI_ATTR_WR_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS)) < 0) return lc8901a_initCleanUp (rmSession, instrSession, lc8901a_status); if ((lc8901a_status = viSetAttribute (*instrSession, VI_ATTR_RD_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS)) < 0) return lc8901a_initCleanUp (rmSession, instrSession, lc8901a_status); if (( (lc8901a_status == OpenDev ("", "")) < 0 )) return lc8901a_status; viSetAttribute (*instrSession, VI_ATTR_GPIB_READDR_EN, VI_TRUE); // Call Mode Function lc8901a_status = lc8901a_Mode (*instrSession, transferMode, dataWord); return lc8901a_status; } /*****************************************************************************/ /*-------- INSERT USER-CALLABLE INSTRUMENT-DEPENDENT ROUTINES HERE ----------*/ /*****************************************************************************/ /*===========================================================================*/ /* Function: Mode */ /* Purpose: This function is used to specifiy the mode for all subsequent */ /* writes and reads to and from the LC 8901A. The transfer mode and */ /* length of data are configured through this function. */ /*===========================================================================*/ ViStatus _VI_FUNC lc8901a_Mode (ViSession instrSession, ViInt16 transferMode, ViInt16 dataWord) { ViStatus lc8901a_status = VI_SUCCESS; ViInt16 mode; ViUInt32 writtenCount; ViByte writeBuffer[1]; ViInt16 mod[3] = {97,121,105}; ViInt16 dat[3] = {0,1,3}; if ( lc8901a_invalidViInt16Range (dataWord,0,2) ){ return VI_ERROR_PARAMETER2; } if ( lc8901a_invalidViInt16Range (transferMode,0,2) ){ return VI_ERROR_PARAMETER3; } viSetAttribute (instrSession, VI_ATTR_GPIB_UNADDR_EN, VI_TRUE); mode = (transferMode*3) + dataWord; writeBuffer[0] = (ViByte) ( mod[transferMode]+dat[dataWord] ); if( (lc8901a_status = viWrite (instrSession, writeBuffer , 1, &writtenCount)) < 0){ return lc8901a_status; } viSetAttribute (instrSession, VI_ATTR_USER_DATA, mode); viSetAttribute (instrSession, VI_ATTR_GPIB_UNADDR_EN, VI_FALSE); return lc8901a_status; } /*===========================================================================*/ /* Function: Write */ /* Purpose: This function is used to write to the LC 8901A. The "Data" */ /* variable will be ignored for functions that do not require it. */ /* The function should not be used to send the command to perform a */ /* read from the Crate Controller, the command and read are */ /* performed together in the "lc8901a_Read" function. */ /*===========================================================================*/ ViStatus _VI_FUNC lc8901a_Write (ViSession instrSession, ViInt16 f, ViInt16 a, ViInt16 n, long data) { ViStatus lc8901a_status = VI_SUCCESS; ViUInt32 count; ViInt16 mode; ViUInt32 writeLength; ViByte buffer[7]; if( lc8901a_invalidViInt16Range (f,8,31) ){ return VI_ERROR_PARAMETER2; } if( lc8901a_invalidViInt16Range (a,0,15) ){ return VI_ERROR_PARAMETER3; } if( lc8901a_invalidViInt16Range (n,0,31) ){ return VI_ERROR_PARAMETER4; } // Get Instrument Mode // if Mode modulus 3 == 0 - 8 Bit Mode // if Mode modulus 3 == 1 - 16 Bit Mode // if Mode modulus 3 == 2 - 24 Bit Mode viGetAttribute (instrSession, VI_ATTR_USER_DATA, &mode); buffer[0] = (ViByte) f; buffer[1] = (ViByte) a; buffer[2] = (ViByte) n; // If the specified function requires data to be sent. if( (f>15) && (f<24) ){ buffer[3] = data; buffer[4] = (ViByte) (data>>8); buffer[5] = (ViByte) (data>>16); switch( mode%3 ){ case 0: writeLength = 4; break; case 1: writeLength = 5; break; case 2: writeLength = 6; break; } } // If the specified function doesn't require data to be sent. else{ writeLength = 3; } if ( (lc8901a_status = viWrite (instrSession, buffer, writeLength, &count)) < 0){ return lc8901a_status; } // This issues a "Talk", necessary to upload the CAMAC command. if ( (lc8901a_status = viRead (instrSession, buffer, 5, &count)) < 0 ){ return lc8901a_status; } return lc8901a_status; } /*===========================================================================*/ /* Function: Read */ /* Purpose: This function is used read data from the CAMAC crate through */ /* the LC8901A GPIB Interface. */ /*===========================================================================*/ ViStatus _VI_FUNC lc8901a_Read (ViSession instrSession, ViInt16 f, ViInt16 a, ViInt16 n, ViInt32 blockCount, ViInt32 timeoutValue, ViInt32 *data, ViBoolean *x, ViBoolean *q) { ViStatus lc8901a_status = VI_SUCCESS; ViInt16 mode; ViInt32 dataSize, currTOVal; ViByte buffer[3], *readBuffer = VI_NULL; ViUInt32 count, pointsRead; int i,j; if( lc8901a_invalidViInt16Range (f,0,7) ){ return VI_ERROR_PARAMETER2; } if( lc8901a_invalidViInt16Range (a,0,15) ){ return VI_ERROR_PARAMETER3; } if( lc8901a_invalidViInt16Range (n,0,31) ){ return VI_ERROR_PARAMETER4; } if( timeoutValue < 0 ){ return VI_ERROR_PARAMETER5; } if( blockCount < 1 ){ return VI_ERROR_PARAMETER6; } // Get Instrument Mode // if Mode modulus 3 == 0 - 8 Bit Mode // if Mode modulus 3 == 1 - 16 Bit Mode // if Mode modulus 3 == 2 - 24 Bit Mode viGetAttribute (instrSession, VI_ATTR_USER_DATA, &mode); buffer[0] = (ViByte) f; buffer[1] = (ViByte) a; buffer[2] = (ViByte) n; if ( (lc8901a_status = viWrite (instrSession, buffer, 3, &count)) < 0){ return lc8901a_status; } viGetAttribute (instrSession, VI_ATTR_TMO_VALUE, &currTOVal); viSetAttribute (instrSession, VI_ATTR_TMO_VALUE, timeoutValue); // Set blockCount to 1 if the instrument mode is in Single Transfer Mode. if( mode<3 ){ blockCount = 1; } // Calculate the size of the array that will be needed to read back // the requested data. switch( mode%3 ){ case 0: dataSize = blockCount+1; break; case 1: dataSize = (blockCount*2)+1; break; case 2: dataSize = (blockCount*3)+1; break; } // Allocate the memory needed to read back the requested data if ((readBuffer = malloc( dataSize+1 )) == VI_NULL) return VI_ERROR_ALLOC; if ( (lc8901a_status = viRead (instrSession, readBuffer, (dataSize+1) , &count)) < 0 ) { viSetAttribute (instrSession, VI_ATTR_TMO_VALUE, currTOVal); free (readBuffer); return lc8901a_status; } viSetAttribute (instrSession, VI_ATTR_TMO_VALUE, currTOVal); // Convert the read data into signed 32 bit integers and store into the array // passed into the function. switch( mode%3 ){ case 0: pointsRead = count-1; Scan (readBuffer, "%*i[b1]>%*i[b4]", pointsRead, pointsRead, data); break; case 1: pointsRead = (count-1)/2; Scan (readBuffer, "%*i[b2]>%*i[b4]", pointsRead, pointsRead, data); break; case 2: pointsRead = (count-1)/3; Scan (readBuffer, "%*i[b3]>%*i[b4]", pointsRead, pointsRead, data); break; } // Read and assign x and q conditions. if( (1 & readBuffer[count-1] ) ){ *x = 1; } if( (2 & readBuffer[count-1] ) ){ *q = 1; } free (readBuffer); return lc8901a_status; } /*===========================================================================*/ /* Function: Initialize Clear Inhibit */ /* Purpose: This function is used to assert a CAMAC Initialize (Z), */ /* Clear (C) or Inhibit (I). In addition Inhibit can be deasserted */ /* through this function. */ /*===========================================================================*/ ViStatus _VI_FUNC lc8901a_InitClearInhibit (ViSession instrSession, ViInt16 command) { ViStatus lc8901a_status = VI_SUCCESS; ViUInt32 count; ViInt16 commandCode[5] = {33,34,35,72,64}; ViByte buffer[5]; if ( lc8901a_invalidViInt16Range (command,0,4) ){ return VI_ERROR_PARAMETER2; } buffer[0] = (ViByte) commandCode[command]; if ( (lc8901a_status = viWrite (instrSession, buffer, 1, &count)) < 0){ return lc8901a_status; } if ( (lc8901a_status = viRead (instrSession, buffer, 5, &count)) < 0 ){ return lc8901a_status; } return lc8901a_status; } /*===========================================================================*/ /* Function: Set SRQ */ /* Purpose: This function sets or configures the conditions on which SRQ is */ /* to be enabled. */ /*===========================================================================*/ ViStatus _VI_FUNC lc8901a_SetSRQ (ViSession instrSession, int SRQCondition) { ViStatus lc8901a_status = VI_SUCCESS; ViUInt32 writtenCount; ViByte writeBuffer[1]; if ( lc8901a_invalidViInt16Range (SRQCondition,0,7) ){ return VI_ERROR_PARAMETER2; } viSetAttribute (instrSession, VI_ATTR_GPIB_UNADDR_EN, VI_TRUE); if( SRQCondition != 0 ){ if ( (lc8901a_status = viEnableEvent (instrSession, VI_EVENT_SERVICE_REQ, VI_QUEUE, VI_NULL)) < 0){ return lc8901a_status; } if ( (lc8901a_status = viDiscardEvents (instrSession, VI_ALL_ENABLED_EVENTS, VI_QUEUE)) < 0){ return lc8901a_status; } } // Set the corresponding command for the SRQCondition selected writeBuffer[0] = 64 + SRQCondition; // Send the SRQ Condition command to the instrument if ( (lc8901a_status = viWrite (instrSession, writeBuffer , 1, &writtenCount)) < 0){ return lc8901a_status; } viSetAttribute (instrSession, VI_ATTR_GPIB_UNADDR_EN, VI_FALSE); // If SRQCondition is set to disable SRQ then disable srqs for the session if( SRQCondition == 0 ){ if ( (lc8901a_status = viDisableEvent (instrSession, VI_ALL_ENABLED_EVENTS, VI_QUEUE)) < 0){ return lc8901a_status; } } return lc8901a_status; } /*===========================================================================*/ /* Function: Wait For SRQ */ /* Purpose: This function sets or configures the conditions on which SRQ is */ /* to be enabled. */ /*===========================================================================*/ ViStatus _VI_FUNC lc8901a_WaitSRQ (ViSession instrSession, long timeOut, short lamResponse[], ViBoolean *x, ViBoolean *q) { ViStatus lc8901a_status = VI_SUCCESS; ViBuf command = (ViBuf) 64; ViChar buffer[5]; ViUInt32 count, instrAddress; ViChar mask; int i,j; ViByte writeBuffer[2]; if( timeOut < 0 ){ return VI_ERROR_PARAMETER2; } if ((lc8901a_status = viWaitOnEvent (instrSession, VI_EVENT_SERVICE_REQ, timeOut, VI_NULL, VI_NULL)) < 0){ viDisableEvent (instrSession, VI_ALL_ENABLED_EVENTS, VI_QUEUE); return lc8901a_status; } viSetAttribute (instrSession, VI_ATTR_GPIB_UNADDR_EN, VI_TRUE); // Send the SRQ Disable Condition command to the instrument if ( (lc8901a_status = viWrite (instrSession, command , 1, VI_NULL)) < 0){ return lc8901a_status; } viSetAttribute (instrSession, VI_ATTR_GPIB_UNADDR_EN, VI_FALSE); viGetAttribute (instrSession, VI_ATTR_GPIB_PRIMARY_ADDR, &instrAddress); *writeBuffer = 64+instrAddress; ibwrt (0, writeBuffer, 1); ibwrt (0, "\x18", 1); // Read the service request response if ( (lc8901a_status = viRead (instrSession, buffer, 5, &count)) < 0 ){ return lc8901a_status; } ibwrt (0, "\x19", 1); // Disable SRQ for the instrument session if ( (lc8901a_status = viDisableEvent (instrSession, VI_ALL_ENABLED_EVENTS, VI_QUEUE)) < 0){ return lc8901a_status; } // Calculate and assign the lamResponse array to return the modules // that asserted a Lam for ( i=1; i < count; i++ ){ mask = (ViChar) 1; for ( j=0; j<5; j++ ){ if ( ( buffer[i] & mask) > 0 ){ lamResponse[((i-1)*6)+j] = 1; } else{ lamResponse[((i-1)*6)+j] = 0; } mask <<= 1; } } for ( i=(6*(count-1)); i<32; i++){ lamResponse[i] = 0; } // Read and assign x and q conditions. if( (1 & buffer[0] ) ){ *x = 1; } if( (2 & buffer[0] ) ){ *q = 1; } return lc8901a_status; } /*===========================================================================*/ /* Function: Error Message */ /* Purpose: This function translates the error return value from the */ /* instrument driver into a user-readable string. */ /*===========================================================================*/ ViStatus _VI_FUNC lc8901a_errorMessage (ViSession instrSession, ViStatus statusCode, ViChar _VI_FAR errMessage[]) { ViStatus lc8901a_status = VI_SUCCESS; ViInt16 i; static lc8901a_tStringValPair statusDescArray[] = { {VI_WARN_NSUP_ID_QUERY, "WARNING: ID Query not supported"}, {VI_WARN_NSUP_RESET, "WARNING: Reset not supported"}, {VI_WARN_NSUP_SELF_TEST, "WARNING: Self-test not supported"}, {VI_WARN_NSUP_ERROR_QUERY, "WARNING: Error Query not supported"}, {VI_WARN_NSUP_REV_QUERY, "WARNING: Revision Query not supported"}, {VI_ERROR_PARAMETER1, "ERROR: Parameter 1 out of range"}, {VI_ERROR_PARAMETER2, "ERROR: Parameter 2 out of range"}, {VI_ERROR_PARAMETER3, "ERROR: Parameter 3 out of range"}, {VI_ERROR_PARAMETER4, "ERROR: Parameter 4 out of range"}, {VI_ERROR_PARAMETER5, "ERROR: Parameter 5 out of range"}, {VI_ERROR_PARAMETER6, "ERROR: Parameter 6 out of range"}, {VI_ERROR_PARAMETER7, "ERROR: Parameter 7 out of range"}, {VI_ERROR_PARAMETER8, "ERROR: Parameter 8 out of range"}, {VI_ERROR_FAIL_ID_QUERY,"ERROR: Identification query failed"}, {VI_ERROR_INV_RESPONSE, "ERROR: Interpreting instrument response"}, {VI_ERROR_INSTR_FILE_OPEN, "ERROR: Opening the specified file"}, {VI_ERROR_INSTR_FILE_WRITE, "ERROR: Writing to the specified file"}, {VI_ERROR_INSTR_INTERPRETING_RESPONSE, "ERROR: Interpreting the instrument's response"}, {VI_ERROR_INSTR_PARAMETER9 , "ERROR: Parameter 9 out of range"}, {VI_ERROR_INSTR_PARAMETER10, "ERROR: Parameter 10 out of range"}, {VI_ERROR_INSTR_PARAMETER11, "ERROR: Parameter 11 out of range"}, {VI_ERROR_INSTR_PARAMETER12, "ERROR: Parameter 12 out of range"}, {VI_ERROR_INSTR_PARAMETER13, "ERROR: Parameter 13 out of range"}, {VI_ERROR_INSTR_PARAMETER14, "ERROR: Parameter 14 out of range"}, {VI_ERROR_INSTR_PARAMETER15, "ERROR: Parameter 15 out of range"}, {VI_NULL, VI_NULL} }; lc8901a_status = viStatusDesc (instrSession, statusCode, errMessage); if (lc8901a_status == VI_WARN_UNKNOWN_STATUS) { for (i = 0; statusDescArray[i].stringName; i++) { if (statusDescArray[i].stringVal == statusCode) { Fmt (errMessage, "%s<%s", statusDescArray[i].stringName); return (VI_SUCCESS); } } Fmt (errMessage, "%s max) ? VI_TRUE : VI_FALSE); } /*===========================================================================*/ /* Function: Long Signed Integer Value Out Of Range - ViInt32 */ /* Purpose: This function checks a long signed integer value to see if it */ /* lies between a minimum and maximum value. If the value is out */ /* of range, the return value is VI_TRUE, otherwise the return */ /* value is VI_FALSE. */ /*===========================================================================*/ ViBoolean lc8901a_invalidViInt32Range (ViInt32 val, ViInt32 min, ViInt32 max) { return ((val < min || val > max) ? VI_TRUE : VI_FALSE); } /*===========================================================================*/ /* Function: Unsigned Char Value Out Of Range - ViUInt8 */ /* Purpose: This function checks an unsigned char value to see if it */ /* lies between a minimum and maximum value. If the value is out */ /* of range, the return value is VI_TRUE, otherwise the return */ /* value is VI_FALSE. */ /*===========================================================================*/ ViBoolean lc8901a_invalidViUInt8Range (ViUInt8 val, ViUInt8 min, ViUInt8 max) { return ((val < min || val > max) ? VI_TRUE : VI_FALSE); } /*===========================================================================*/ /* Function: Short Unsigned Integer Value Out Of Range - ViUInt16 */ /* Purpose: This function checks a short unsigned integer value to see if it*/ /* lies between a minimum and maximum value. If the value is out */ /* of range, the return value is VI_TRUE, otherwise the return */ /* value is VI_FALSE. */ /*===========================================================================*/ ViBoolean lc8901a_invalidViUInt16Range (ViUInt16 val, ViUInt16 min, ViUInt16 max) { return ((val < min || val > max) ? VI_TRUE : VI_FALSE); } /*===========================================================================*/ /* Function: Long Unsigned Integer Value Out Of Range - ViUInt32 */ /* Purpose: This function checks a long unsigned integer value to see if it */ /* lies between a minimum and maximum value. If the value is out */ /* of range, the return value is VI_TRUE, otherwise the return */ /* value is VI_FALSE. */ /*===========================================================================*/ ViBoolean lc8901a_invalidViUInt32Range (ViUInt32 val, ViUInt32 min, ViUInt32 max) { return ((val < min || val > max) ? VI_TRUE : VI_FALSE); } /*===========================================================================*/ /* Function: Real (Float) Value Out Of Range - ViReal32 */ /* Purpose: This function checks a real (float) value to see if it lies */ /* between a minimum and maximum value. If the value is out of */ /* range, the return value is VI_TRUE, otherwise the return value */ /* is VI_FALSE. */ /*===========================================================================*/ ViBoolean lc8901a_invalidViReal32Range (ViReal32 val, ViReal32 min, ViReal32 max) { return ((val < min || val > max) ? VI_TRUE : VI_FALSE); } /*===========================================================================*/ /* Function: Real (Double) Value Out Of Range - ViReal64 */ /* Purpose: This function checks a real (double) value to see if it lies */ /* between a minimum and maximum value. If the value is out of */ /* range, the return value is VI_TRUE, otherwise the return value */ /* is VI_FALSE. */ /*===========================================================================*/ ViBoolean lc8901a_invalidViReal64Range (ViReal64 val, ViReal64 min, ViReal64 max) { return ((val < min || val > max) ? VI_TRUE : VI_FALSE); } /*================================================================================*/ /* Function: Wait On VISA Event */ /* Purpose: This function waits for the occurrence of an enabled VISA Event. The */ /* event type must be enabled before entering this function. Any */ /* programmatic commands, actions, or conditions, necessary to generate */ /* the specified event type, must be satisified before entering this */ /* function. The function will wait for the specified timeout and then */ /* return. If the specified event is received then the function will */ /* return VI_SUCCESS (0), otherwise the status code for the generated */ /* error will be returned. In either case the function will disable the */ /* event type and deallocate the event handle passed from viWaitOnEvent */ /* before returning. WARNING: If VI_TMO_INFINITE is passed in as the */ /* timeout this function WILL NOT return until the specified event is */ /* received, if the event is not received the function will not return */ /* and it will be necessary to terminate CVI in order to regain control.*/ /*================================================================================*/ ViStatus lc8901a_waitOnVisaEvent (ViSession instrSession, ViEventType eventTypeIn, ViUInt32 timeoutIn, ViPUInt16 STB) { ViStatus lc8901a_status = VI_SUCCESS, tempStatus = VI_SUCCESS; ViEventType eventTypeOut = 0; ViEvent eventHandle = 0; /* For debug purposes we want to be able to see the status returned by */ /* viDisableEvent and viClose if one of the internal functions fails but do */ /* not want to return that value as that is not where the initial error */ /* occurs in the function, so we assign it to tempStatus. */ if ((lc8901a_status = viWaitOnEvent (instrSession, eventTypeIn, timeoutIn, &eventTypeOut, &eventHandle)) < 0) { tempStatus = viDisableEvent (instrSession, eventTypeIn, VI_QUEUE); return lc8901a_status; } if (eventTypeIn == VI_EVENT_SERVICE_REQ) if ((lc8901a_status = viReadSTB (instrSession, STB)) < 0) { tempStatus = viClose (eventHandle); tempStatus = viDisableEvent (instrSession, eventTypeIn, VI_QUEUE); return lc8901a_status; } if ((lc8901a_status = viClose (eventHandle)) < 0) { tempStatus = viDisableEvent (instrSession, eventTypeIn, VI_QUEUE); return lc8901a_status; } if ((lc8901a_status = viDisableEvent (instrSession, eventTypeIn, VI_QUEUE)) < 0) return lc8901a_status; return lc8901a_status; } //*===========================================================================* //* Function: Initialize Clean Up * //* Purpose: This function is used only by the lc8901a_init function. When * //* an error is detected this function is called to close the * //* open resource manager and instrument object sessions and to * //* set the instrSession that is returned from lc8901a_init to * //* VI_NULL. * //*===========================================================================* ViStatus lc8901a_initCleanUp (ViSession openRMSession, ViPSession openInstrSession, ViStatus currentStatus) { lc8901a_instrRange instrPtr; viClose (*openInstrSession); viClose (openRMSession); *openInstrSession = VI_NULL; return currentStatus; }