|
/*****************************************************************************
|
|
/*=CHANGE:===============================================================*
|
|
Change the copyright note.
|
|
*=======================================================================*
|
|
* Copyright 2009, National Instruments, Corporation. All Rights Reserved. *
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
/*=CHANGE:===============================================================*
|
|
INSTRUCTIONS TO THE INSTRUMENT DRIVER DEVELOPER
|
|
READ THESE INSTRUCTIONS FIRST!
|
|
*=======================================================================*
|
|
|
|
Congratulations! You have successfully created all the files needed
|
|
for your instrument driver - *.c, *.h, *.fp, and *.sub. These
|
|
files give you a framework to build your complete instrument driver
|
|
with the following features:
|
|
- IVI compliance
|
|
- VXIplug&play compliance
|
|
- Attribute model
|
|
- State caching
|
|
- Simulation
|
|
- Multithread safety
|
|
|
|
Before you can begin using this driver, you must perform the following
|
|
manual changes.
|
|
|
|
- If you are developing a driver for a register-based device,
|
|
remove the function panels for the inst_WriteInstrData
|
|
and inst_ReadInstrData functions. These functions
|
|
are for use with message-based instruments.
|
|
|
|
- Device-specific changes are marked with the comment "CHANGE".
|
|
Search for all occurrences of the word "CHANGE" and make the changes
|
|
for your specific instrument. Delete the comments after you complete
|
|
the changes.
|
|
|
|
- The IVI wizard might not properly align the code it generates.
|
|
Review the resulting *.h and *.c files and reformat them as necessary.
|
|
|
|
- Read the help text for the functions and attributes to understand
|
|
the functionality you must implement in this driver. The easiest
|
|
way to view the help text is by using the inst.fp
|
|
function panels in "operate" mode. You can view the help text for
|
|
the attributes in any of the inst_GetAttribute
|
|
function panels.
|
|
|
|
- Many of the functions contain extensive code examples within
|
|
comment blocks. These code examples contain embedded comments.
|
|
The only way to embed comments is by using double slashes (//).
|
|
Some C compilers do not accept double slashes. If you are developing
|
|
this driver for general use, convert the double slashes to
|
|
traditional C comment markers.
|
|
|
|
- Edit the Function Panel help. Pay close attention to the default
|
|
values and valid ranges for each parameter. If you change the
|
|
default value for a control, you also need to change the default
|
|
value in the help for the control. Also, search for the comment
|
|
"CHANGE" in the help text, and make the appropriate changes.
|
|
|
|
- Edit the help for all attributes with the attribute editor. Pay close
|
|
attention to the valid range information. The Set/Get/Check attribute
|
|
function panels automatically display valid range information for
|
|
attributes that have range tables of type IVI_VAL_DISCRETE or
|
|
IVI_VAL_COERCED. You must edit/create the valid range information
|
|
in the description of an attribute if any of the following conditions
|
|
is true:
|
|
* The attribute does not have a range table.
|
|
* The attribute has a range table of type IVI_VAL_RANGED.
|
|
* The attribute uses multiple static range tables or a dynamic
|
|
range table.
|
|
|
|
Also, look for "CHANGE" comments in the help text, and make the
|
|
appropriate changes.
|
|
|
|
- Verify that all values that the header file defines are valid for
|
|
your instrument. Delete the values that your instrument does not
|
|
use.
|
|
|
|
- Delete these instructions and save the modified program.
|
|
|
|
*============================================================END=CHANGE=*/
|
|
|
|
/*****************************************************************************
|
|
* inst Instrument Driver
|
|
* LabWindows/CVI Instrument Driver
|
|
* Original Release: lundi 17 octobre 2011
|
|
* By: ,
|
|
* PH. Fax
|
|
*
|
|
* Modification History:
|
|
*
|
|
* lundi 17 octobre 2011 - Instrument Driver Created.
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include <string.h>
|
|
#include <stdio.h>
|
|
#include <formatio.h>
|
|
#include "inst.h"
|
|
|
|
/*****************************************************************************
|
|
*--------------------- Hidden Attribute Declarations -----------------------*
|
|
*****************************************************************************/
|
|
|
|
#define INST_ATTR_OPC_TIMEOUT (IVI_SPECIFIC_PRIVATE_ATTR_BASE + 1L) /* ViInt32 */
|
|
#define INST_ATTR_USE_SPECIFIC_SIMULATION (IVI_INHERENT_ATTR_BASE + 23L) /* ViBoolean */
|
|
#define INST_ATTR_VISA_RM_SESSION (IVI_SPECIFIC_PRIVATE_ATTR_BASE + 5L) /* ViSession */
|
|
#define INST_ATTR_IO_SESSION (IVI_INHERENT_ATTR_BASE + 322L) /* ViSession */
|
|
#define INST_ATTR_OPC_CALLBACK (IVI_SPECIFIC_PRIVATE_ATTR_BASE + 6L) /* ViAddr */
|
|
#define INST_ATTR_CHECK_STATUS_CALLBACK (IVI_SPECIFIC_PRIVATE_ATTR_BASE + 7L) /* ViAddr */
|
|
#define INST_ATTR_USER_INTERCHANGE_CHECK_CALLBACK (IVI_SPECIFIC_PRIVATE_ATTR_BASE + 8L) /* ViAddr */
|
|
|
|
/*****************************************************************************
|
|
*---------------------------- Useful Macros --------------------------------*
|
|
*****************************************************************************/
|
|
|
|
/*- I/O buffer size -----------------------------------------------------*/
|
|
#define BUFFER_SIZE 512L
|
|
|
|
/*=CHANGE:=============================================================*
|
|
NOTE TO THE DEVELOPER: The attribute for which this value is defined
|
|
is obsolete and may not be supported in future versions of IVI drivers.
|
|
|
|
If you DO NOT want this driver to be compliant with NI's Ivi Driver
|
|
Toolset 1.1, remove this value definition.
|
|
|
|
If you DO want this driver to be compliant with NI's IVI Driver Toolset
|
|
1.1, remove the comments around this attribute value definition.
|
|
|
|
#define INST_IO_SESSION_TYPE IVI_VAL_VISA_SESSION_TYPE
|
|
*==========================================================END=CHANGE=*/
|
|
|
|
/*- 488.2 Event Status Register (ESR) Bits ------------------------------*/
|
|
#define IEEE_488_2_ERROR_MASK 0x3C
|
|
|
|
|
|
/*****************************************************************************
|
|
*-------------- Utility Function Declarations (Non-Exported) ---------------*
|
|
*****************************************************************************/
|
|
static ViStatus inst_IviInit (ViRsrc resourceName, ViBoolean IDQuery,
|
|
ViBoolean reset, ViSession vi);
|
|
static ViStatus inst_IviClose (ViSession vi);
|
|
|
|
static ViStatus inst_InitAttributes (ViSession vi);
|
|
static ViStatus inst_DefaultInstrSetup (ViSession openInstrSession);
|
|
static ViStatus inst_CheckStatus (ViSession vi);
|
|
static ViStatus inst_WaitForOPC (ViSession vi, ViInt32 maxTime);
|
|
|
|
/*- File I/O Utility Functions -*/
|
|
static ViStatus inst_ReadToFile (ViSession vi, ViConstString filename,
|
|
ViInt32 maxBytesToRead, ViInt32 fileAction, ViInt32 *totalBytesWritten);
|
|
static ViStatus inst_WriteFromFile (ViSession vi, ViConstString filename,
|
|
ViInt32 maxBytesToWrite, ViInt32 byteOffset,
|
|
ViInt32 *totalBytesWritten);
|
|
|
|
/*****************************************************************************
|
|
*----------------- Callback Declarations (Non-Exported) --------------------*
|
|
*****************************************************************************/
|
|
|
|
/*- Global Session Callbacks --------------------------------------------*/
|
|
|
|
static ViStatus _VI_FUNC inst_CheckStatusCallback (ViSession vi, ViSession io);
|
|
static ViStatus _VI_FUNC inst_WaitForOPCCallback (ViSession vi, ViSession io);
|
|
|
|
/*- Attribute callbacks -------------------------------------------------*/
|
|
|
|
static ViStatus _VI_FUNC instAttrDriverRevision_ReadCallback (ViSession vi,
|
|
ViSession io,
|
|
ViConstString channelName,
|
|
ViAttr attributeId,
|
|
const ViConstString cacheValue);
|
|
static ViStatus _VI_FUNC instAttrInstrumentManufacturer_ReadCallback (ViSession vi,
|
|
ViSession io,
|
|
ViConstString channelName,
|
|
ViAttr attributeId,
|
|
const ViConstString cacheValue);
|
|
static ViStatus _VI_FUNC instAttrInstrumentModel_ReadCallback (ViSession vi,
|
|
ViSession io,
|
|
ViConstString channelName,
|
|
ViAttr attributeId,
|
|
const ViConstString cacheValue);
|
|
|
|
|
|
/*****************************************************************************
|
|
*------------ User-Callable Functions (Exportable Functions) ---------------*
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_init
|
|
* Purpose: VXIplug&play required function. Calls the
|
|
* inst_InitWithOptions function.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_init (ViRsrc resourceName, ViBoolean IDQuery,
|
|
ViBoolean resetDevice, ViSession *newVi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
if (newVi == VI_NULL)
|
|
{
|
|
Ivi_SetErrorInfo (VI_NULL, VI_FALSE, IVI_ERROR_INVALID_PARAMETER,
|
|
VI_ERROR_PARAMETER4, "Null address for Instrument Handle");
|
|
checkErr( IVI_ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
checkErr( inst_InitWithOptions (resourceName, IDQuery, resetDevice,
|
|
"", newVi));
|
|
|
|
Error:
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_InitWithOptions
|
|
* Purpose: This function creates a new IVI session and calls the
|
|
* IviInit function.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_InitWithOptions(
|
|
ViRsrc resourceName,
|
|
ViBoolean IDQuery,
|
|
ViBoolean resetDevice,
|
|
ViConstString optionString,
|
|
ViSession *newVi
|
|
)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
ViSession vi = VI_NULL;
|
|
ViChar newResourceName[IVI_MAX_MESSAGE_BUF_SIZE];
|
|
ViChar newOptionString[IVI_MAX_MESSAGE_BUF_SIZE];
|
|
ViBoolean isLogicalName;
|
|
|
|
if (newVi == VI_NULL)
|
|
{
|
|
Ivi_SetErrorInfo (VI_NULL, VI_FALSE, IVI_ERROR_INVALID_PARAMETER,
|
|
VI_ERROR_PARAMETER5, "Null address for Instrument Handle");
|
|
checkErr( IVI_ERROR_INVALID_PARAMETER);
|
|
}
|
|
|
|
*newVi = VI_NULL;
|
|
|
|
checkErr( Ivi_GetInfoFromResourceName( resourceName, (ViString)optionString,
|
|
newResourceName,
|
|
newOptionString,
|
|
&isLogicalName));
|
|
|
|
/* create a new interchangeable driver */
|
|
checkErr( Ivi_SpecificDriverNew ("inst", newOptionString, &vi));
|
|
if (!isLogicalName)
|
|
{
|
|
ViInt32 oldFlag = 0;
|
|
|
|
checkErr (Ivi_GetAttributeFlags (vi, IVI_ATTR_IO_RESOURCE_DESCRIPTOR, &oldFlag));
|
|
checkErr (Ivi_SetAttributeFlags (vi, IVI_ATTR_IO_RESOURCE_DESCRIPTOR, oldFlag & 0xfffb | 0x0010));
|
|
checkErr (Ivi_SetAttributeViString (vi, "", IVI_ATTR_IO_RESOURCE_DESCRIPTOR, 0, newResourceName));
|
|
}
|
|
/* init the driver */
|
|
checkErr( inst_IviInit (newResourceName, IDQuery, resetDevice, vi));
|
|
if (isLogicalName)
|
|
checkErr( Ivi_ApplyDefaultSetup (vi));
|
|
*newVi = vi;
|
|
|
|
Error:
|
|
if (error < VI_SUCCESS)
|
|
Ivi_Dispose (vi);
|
|
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_close
|
|
* Purpose: This function closes the instrument.
|
|
*
|
|
* Note: This function must unlock the session before calling
|
|
* Ivi_Dispose.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_close (ViSession vi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
checkErr( Ivi_LockSession (vi, VI_NULL));
|
|
|
|
checkErr( inst_IviClose (vi));
|
|
|
|
Error:
|
|
Ivi_UnlockSession (vi, VI_NULL);
|
|
Ivi_Dispose (vi);
|
|
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_reset
|
|
* Purpose: This function resets the instrument.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_reset (ViSession vi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
checkErr( Ivi_LockSession (vi, VI_NULL));
|
|
|
|
|
|
checkErr( inst_DefaultInstrSetup (vi));
|
|
|
|
if ( error == VI_SUCCESS )
|
|
viCheckWarn( VI_WARN_NSUP_RESET);
|
|
|
|
Error:
|
|
Ivi_UnlockSession (vi, VI_NULL);
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_ResetWithDefaults
|
|
* Purpose: This function resets the instrument and applies default settings
|
|
* from the IVI Configuration Store based on the logical name
|
|
* from which the session was created.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_ResetWithDefaults (ViSession vi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
checkErr( Ivi_LockSession (vi, VI_NULL));
|
|
checkErr( inst_reset(vi));
|
|
checkErr( Ivi_ApplyDefaultSetup(vi));
|
|
|
|
Error:
|
|
Ivi_UnlockSession(vi, VI_NULL);
|
|
return error;
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Function: inst_Disable
|
|
* Purpose: This function places the instrument in a quiescent state as
|
|
* quickly as possible.
|
|
****************************************************************************/
|
|
ViStatus _VI_FUNC inst_Disable (ViSession vi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
checkErr( Ivi_LockSession (vi, VI_NULL));
|
|
|
|
if (!Ivi_Simulating(vi))
|
|
{
|
|
/*=CHANGE:===============================================================*
|
|
|
|
Modify this example code to disable the instrument.
|
|
|
|
ViSession io = Ivi_IOSession(vi); // call only when locked
|
|
|
|
checkErr( Ivi_SetNeedToCheckStatus (vi, VI_TRUE));
|
|
|
|
viCheckErr( viPrintf (io, ":OPER:CH:ALL:OFF;"));
|
|
*============================================================END=CHANGE=*/
|
|
}
|
|
Error:
|
|
Ivi_UnlockSession (vi, VI_NULL);
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_self_test
|
|
* Purpose: This function executes the instrument self-test and returns the
|
|
* result.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_self_test (ViSession vi, ViInt16 *testResult,
|
|
ViChar testMessage[])
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
checkErr( Ivi_LockSession (vi, VI_NULL));
|
|
|
|
if (testResult == VI_NULL)
|
|
viCheckParm( IVI_ERROR_INVALID_PARAMETER, 2, "Null address for Test Result");
|
|
if (testMessage == VI_NULL)
|
|
viCheckParm( IVI_ERROR_INVALID_PARAMETER, 3, "Null address for Test Message");
|
|
|
|
viCheckWarn( VI_WARN_NSUP_SELF_TEST);
|
|
|
|
Error:
|
|
Ivi_UnlockSession(vi, VI_NULL);
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_revision_query
|
|
* Purpose: This function returns the driver and instrument revisions.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_revision_query (ViSession vi, ViChar driverRev[],
|
|
ViChar instrRev[])
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
checkErr( Ivi_LockSession (vi, VI_NULL));
|
|
|
|
if (driverRev == VI_NULL)
|
|
viCheckParm( IVI_ERROR_INVALID_PARAMETER, 2, "Null address for Driver Revision");
|
|
if (instrRev == VI_NULL)
|
|
viCheckParm( IVI_ERROR_INVALID_PARAMETER, 3, "Null address for Instrument Revision");
|
|
|
|
checkErr( Ivi_GetAttributeViString (vi, "", INST_ATTR_SPECIFIC_DRIVER_REVISION,
|
|
0, 256, driverRev));
|
|
checkErr( Ivi_GetAttributeViString (vi, "", INST_ATTR_INSTRUMENT_FIRMWARE_REVISION,
|
|
0, 256, instrRev));
|
|
checkErr( inst_CheckStatus (vi));
|
|
viCheckWarn( VI_WARN_NSUP_REV_QUERY);
|
|
|
|
Error:
|
|
Ivi_UnlockSession(vi, VI_NULL);
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_error_query
|
|
* Purpose: This function queries the instrument error queue and returns
|
|
* the result.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_error_query (ViSession vi, ViInt32 *errCode,
|
|
ViChar errMessage[])
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
checkErr( Ivi_LockSession (vi, VI_NULL));
|
|
|
|
if (errCode == VI_NULL)
|
|
viCheckParm( IVI_ERROR_INVALID_PARAMETER, 2, "Null address for Error Code");
|
|
if (errMessage == VI_NULL)
|
|
viCheckParm( IVI_ERROR_INVALID_PARAMETER, 3, "Null address for Error Message");
|
|
|
|
viCheckWarn( VI_WARN_NSUP_ERROR_QUERY);
|
|
|
|
Error:
|
|
Ivi_UnlockSession(vi, VI_NULL);
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_error_message
|
|
* Purpose: This function translates the error codes returned by this
|
|
* instrument driver into user-readable strings.
|
|
*
|
|
* Note: The caller can pass VI_NULL for the vi parameter. This
|
|
* is useful if one of the init functions fail.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_error_message (ViSession vi, ViStatus errorCode,
|
|
ViChar errorMessage[256])
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
static IviStringValueTable errorTable =
|
|
{
|
|
/*=CHANGE:================================================================*
|
|
Insert instrument driver specific error codes here. Example:
|
|
|
|
{INST_ERROR_TOO_MANY_SAMPLES, "Sample Count cannot exceed 512."},
|
|
*=============================================================END=CHANGE=*/
|
|
{VI_NULL, VI_NULL}
|
|
};
|
|
|
|
if (vi)
|
|
Ivi_LockSession(vi, VI_NULL);
|
|
|
|
/* all VISA and IVI error codes are handled as well as codes in the table */
|
|
if (errorMessage == VI_NULL)
|
|
viCheckParm( IVI_ERROR_INVALID_PARAMETER, 3, "Null address for Error Message");
|
|
|
|
checkErr( Ivi_GetSpecificDriverStatusDesc(vi, errorCode, errorMessage, errorTable));
|
|
|
|
Error:
|
|
if (vi)
|
|
Ivi_UnlockSession(vi, VI_NULL);
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_InvalidateAllAttributes
|
|
* Purpose: This function invalidates the cached value of all attributes.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_InvalidateAllAttributes (ViSession vi)
|
|
{
|
|
return Ivi_InvalidateAllAttributes(vi);
|
|
}
|
|
|
|
/*- Obsolete Error Handling Functions ----------------------------*/
|
|
/*=CHANGE:=============================================================*
|
|
NOTE TO THE DEVELOPER: These functions are obsolete and may not be
|
|
supported in future versions of IVI drivers.
|
|
|
|
If you DO NOT want this driver to be compliant with NI's Ivi Driver
|
|
Toolset 1.1, remove these function definitions.
|
|
|
|
If you DO want this driver to be compliant with NI's IVI Driver Toolset
|
|
1.1, remove the comments around these functions definitions.
|
|
|
|
ViStatus _VI_FUNC inst_GetErrorInfo (ViSession vi, ViStatus *primaryError,
|
|
ViStatus *secondaryError, ViChar errorElaboration[256])
|
|
{
|
|
return Ivi_GetErrorInfo(vi, primaryError, secondaryError, errorElaboration);
|
|
}
|
|
ViStatus _VI_FUNC inst_ClearErrorInfo (ViSession vi)
|
|
{
|
|
return Ivi_ClearErrorInfo (vi);
|
|
}
|
|
*==========================================================END=CHANGE=*/
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_GetError and inst_ClearError Functions
|
|
* Purpose: These functions enable the instrument driver user to
|
|
* get or clear the error information the driver associates with the
|
|
* IVI session.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_GetError (ViSession vi,
|
|
ViStatus *errorCode,
|
|
ViInt32 bufferSize,
|
|
ViChar description[])
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
ViStatus primary = VI_SUCCESS,
|
|
secondary = VI_SUCCESS;
|
|
ViChar elaboration[256] = "";
|
|
ViChar errorMessage[1024] = "";
|
|
ViChar *appendPoint = errorMessage;
|
|
ViInt32 actualSize = 0;
|
|
ViBoolean locked = VI_FALSE;
|
|
|
|
/* Lock Session */
|
|
if (vi != 0)
|
|
{
|
|
checkErr( Ivi_LockSession(vi, &locked));
|
|
}
|
|
|
|
/* Test for nulls and acquire error data */
|
|
if (bufferSize != 0)
|
|
{
|
|
if (errorCode == VI_NULL)
|
|
{
|
|
viCheckParm( IVI_ERROR_INVALID_PARAMETER, 2, "Null address for Error");
|
|
}
|
|
if (description == VI_NULL)
|
|
{
|
|
viCheckParm( IVI_ERROR_INVALID_PARAMETER, 4, "Null address for Description");
|
|
}
|
|
checkErr( Ivi_GetErrorInfo (vi, &primary, &secondary, elaboration));
|
|
}
|
|
|
|
else
|
|
{
|
|
checkErr( Ivi_GetAttributeViString(vi, VI_NULL, IVI_ATTR_ERROR_ELABORATION, 0, 256, elaboration));
|
|
checkErr( Ivi_GetAttributeViInt32(vi, VI_NULL, IVI_ATTR_SECONDARY_ERROR, 0, &secondary));
|
|
checkErr( Ivi_GetAttributeViInt32(vi, VI_NULL, IVI_ATTR_PRIMARY_ERROR, 0, &primary));
|
|
}
|
|
|
|
/* Format data */
|
|
if (primary != VI_SUCCESS)
|
|
{
|
|
ViChar msg[256] = "";
|
|
checkErr( inst_error_message (vi, primary, msg));
|
|
appendPoint += sprintf(appendPoint, "Primary Error: (Hex 0x%08X) %s\n", primary, msg);
|
|
}
|
|
|
|
if (secondary != VI_SUCCESS)
|
|
{
|
|
ViChar msg[256] = "";
|
|
checkErr( inst_error_message (vi, secondary, msg));
|
|
appendPoint += sprintf(appendPoint, "Secondary Error: (Hex 0x%08X) %s\n", secondary, msg);
|
|
}
|
|
|
|
if (elaboration[0])
|
|
{
|
|
sprintf(appendPoint, "Elaboration: %s", elaboration);
|
|
}
|
|
|
|
actualSize = (ViInt32)(strlen(errorMessage) + 1);
|
|
|
|
/* Prepare return values */
|
|
if (bufferSize == 0)
|
|
{
|
|
error = actualSize;
|
|
}
|
|
else
|
|
{
|
|
if (bufferSize > 0)
|
|
{
|
|
if (actualSize > bufferSize)
|
|
{
|
|
error = actualSize;
|
|
actualSize = bufferSize;
|
|
}
|
|
}
|
|
memcpy(description, errorMessage, actualSize-1);
|
|
description[actualSize-1] = '\0';
|
|
}
|
|
|
|
if (errorCode)
|
|
{
|
|
*errorCode = primary;
|
|
}
|
|
|
|
Error:
|
|
/* Unlock Session */
|
|
Ivi_UnlockSession (vi, &locked);
|
|
return error;
|
|
}
|
|
|
|
ViStatus _VI_FUNC inst_ClearError (ViSession vi)
|
|
{
|
|
return Ivi_ClearErrorInfo (vi);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_GetNextCoercionRecord
|
|
* Purpose: This function enables the instrument driver user to obtain
|
|
* the coercion information associated with the IVI session.
|
|
* This function retrieves and clears the oldest instance in which
|
|
* the instrument driver coerced a value the instrument driver user
|
|
* specified to another value.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_GetNextCoercionRecord (ViSession vi,
|
|
ViInt32 bufferSize,
|
|
ViChar record[])
|
|
{
|
|
return Ivi_GetNextCoercionString (vi, bufferSize, record);
|
|
}
|
|
|
|
/****************************************************************************
|
|
* Function: inst_GetNextInterchangeWarning,
|
|
* inst_ResetInterchangeCheck, and
|
|
* inst_ClearInterchangeWarnings
|
|
* Purpose: These functions allow the user to retrieve interchangeability
|
|
* warnings, reset the driver's interchangeability checking
|
|
* state, and clear all previously logged interchangeability warnings.
|
|
****************************************************************************/
|
|
ViStatus _VI_FUNC inst_GetNextInterchangeWarning (ViSession vi,
|
|
ViInt32 bufferSize,
|
|
ViChar warnString[])
|
|
{
|
|
return Ivi_GetNextInterchangeCheckString (vi, bufferSize, warnString);
|
|
}
|
|
|
|
ViStatus _VI_FUNC inst_ResetInterchangeCheck (ViSession vi)
|
|
{
|
|
return Ivi_ResetInterchangeCheck (vi);
|
|
}
|
|
|
|
ViStatus _VI_FUNC inst_ClearInterchangeWarnings (ViSession vi)
|
|
{
|
|
return Ivi_ClearInterchangeWarnings (vi);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_LockSession and inst_UnlockSession Functions
|
|
* Purpose: These functions enable the instrument driver user to lock the
|
|
* session around a sequence of driver calls during which other
|
|
* execution threads must not disturb the instrument state.
|
|
*
|
|
* NOTE: The callerHasLock parameter must be a local variable
|
|
* initialized to VI_FALSE and passed by reference, or you can pass
|
|
* VI_NULL.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_LockSession (ViSession vi, ViBoolean *callerHasLock)
|
|
{
|
|
return Ivi_LockSession(vi,callerHasLock);
|
|
}
|
|
ViStatus _VI_FUNC inst_UnlockSession (ViSession vi, ViBoolean *callerHasLock)
|
|
{
|
|
return Ivi_UnlockSession(vi,callerHasLock);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_GetAttribute<type> Functions
|
|
* Purpose: These functions enable the instrument driver user to get
|
|
* attribute values directly. There are typesafe versions for
|
|
* ViInt32, ViInt64, ViReal64, ViString, ViBoolean, and ViSession
|
|
* attributes.
|
|
*****************************************************************************/
|
|
|
|
/*=CHANGE:=============================================================*
|
|
|
|
NOTE TO THE DEVELOPER: The ViInt64 functions (_GetAttributeViInt64,
|
|
_SetAttributeViInt64, and _CheckAttributeViInt64) are only required
|
|
if your driver implements a ViInt64 attribute. They can be removed
|
|
otherwise.
|
|
|
|
Note: NI's LabWindows/CVI versions earlier than 8.5 do not support
|
|
function panel files that have ViInt64 parameters. If you add a
|
|
ViInt64 attribute in your driver, the functions can be added to the
|
|
function panel file but the file will only be usable in
|
|
LabWindows/CVI 8.5 and later.
|
|
|
|
*==========================================================END=CHANGE=*/
|
|
|
|
ViStatus _VI_FUNC inst_GetAttributeViInt32 (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViInt32 *value)
|
|
{
|
|
return Ivi_GetAttributeViInt32 (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_GetAttributeViInt64 (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViInt64 *value)
|
|
{
|
|
return Ivi_GetAttributeViInt64 (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_GetAttributeViReal64 (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViReal64 *value)
|
|
{
|
|
return Ivi_GetAttributeViReal64 (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_GetAttributeViString (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViInt32 bufSize,
|
|
ViChar value[])
|
|
{
|
|
return Ivi_GetAttributeViString (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
bufSize, value);
|
|
}
|
|
ViStatus _VI_FUNC inst_GetAttributeViBoolean (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViBoolean *value)
|
|
{
|
|
return Ivi_GetAttributeViBoolean (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_GetAttributeViSession (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViSession *value)
|
|
{
|
|
return Ivi_GetAttributeViSession (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_SetAttribute<type> Functions
|
|
* Purpose: These functions enable the instrument driver user to set
|
|
* attribute values directly. There are typesafe versions for
|
|
* ViInt32, ViInt64, ViReal64, ViString, ViBoolean, and ViSession
|
|
* datatypes.
|
|
*****************************************************************************/
|
|
|
|
/*=CHANGE:=============================================================*
|
|
|
|
NOTE TO THE DEVELOPER: The ViInt64 functions (_GetAttributeViInt64,
|
|
_SetAttributeViInt64, and _CheckAttributeViInt64) are only required
|
|
if your driver implements a ViInt64 attribute. They can be removed
|
|
otherwise.
|
|
|
|
Note: NI's LabWindows/CVI versions earlier than 8.5 do not support
|
|
function panel files that have ViInt64 parameters. If you add a
|
|
ViInt64 attribute in your driver, the functions can be added to the
|
|
function panel file but the file will only be usable in
|
|
LabWindows/CVI 8.5 and later.
|
|
|
|
*==========================================================END=CHANGE=*/
|
|
|
|
ViStatus _VI_FUNC inst_SetAttributeViInt32 (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViInt32 value)
|
|
{
|
|
return Ivi_SetAttributeViInt32 (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_SetAttributeViInt64 (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViInt64 value)
|
|
{
|
|
return Ivi_SetAttributeViInt64 (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_SetAttributeViReal64 (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViReal64 value)
|
|
{
|
|
return Ivi_SetAttributeViReal64 (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_SetAttributeViString (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViConstString value)
|
|
{
|
|
return Ivi_SetAttributeViString (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_SetAttributeViBoolean (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViBoolean value)
|
|
{
|
|
return Ivi_SetAttributeViBoolean (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_SetAttributeViSession (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViSession value)
|
|
{
|
|
return Ivi_SetAttributeViSession (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_CheckAttribute<type> Functions
|
|
* Purpose: These functions enable the instrument driver user to check
|
|
* attribute values directly. These functions check the value you
|
|
* specify even if you set the INST_ATTR_RANGE_CHECK
|
|
* attribute to VI_FALSE. There are typesafe versions for ViInt32,
|
|
* ViInt64, ViReal64, ViString, ViBoolean, and ViSession datatypes.
|
|
*****************************************************************************/
|
|
|
|
/*=CHANGE:=============================================================*
|
|
|
|
NOTE TO THE DEVELOPER: The ViInt64 functions (_GetAttributeViInt64,
|
|
_SetAttributeViInt64, and _CheckAttributeViInt64) are only required
|
|
if your driver implements a ViInt64 attribute. They can be removed
|
|
otherwise.
|
|
|
|
Note: NI's LabWindows/CVI versions earlier than 8.5 do not support
|
|
function panel files that have ViInt64 parameters. If you add a
|
|
ViInt64 attribute in your driver, the functions can be added to the
|
|
function panel file but the file will only be usable in
|
|
LabWindows/CVI 8.5 and later.
|
|
|
|
*==========================================================END=CHANGE=*/
|
|
|
|
ViStatus _VI_FUNC inst_CheckAttributeViInt32 (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViInt32 value)
|
|
{
|
|
return Ivi_CheckAttributeViInt32 (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_CheckAttributeViInt64 (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViInt64 value)
|
|
{
|
|
return Ivi_CheckAttributeViInt64 (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_CheckAttributeViReal64 (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViReal64 value)
|
|
{
|
|
return Ivi_CheckAttributeViReal64 (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_CheckAttributeViString (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViConstString value)
|
|
{
|
|
return Ivi_CheckAttributeViString (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_CheckAttributeViBoolean (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViBoolean value)
|
|
{
|
|
return Ivi_CheckAttributeViBoolean (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
ViStatus _VI_FUNC inst_CheckAttributeViSession (ViSession vi, ViConstString channelName,
|
|
ViAttr attributeId, ViSession value)
|
|
{
|
|
return Ivi_CheckAttributeViSession (vi, channelName, attributeId, IVI_VAL_DIRECT_USER_CALL,
|
|
value);
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* Function: WriteInstrData and ReadInstrData Functions
|
|
* Purpose: These functions enable the instrument driver user to
|
|
* write and read commands directly to and from the instrument.
|
|
*
|
|
* Note: These functions bypass the IVI attribute state caching.
|
|
* WriteInstrData invalidates the cached values for all
|
|
* attributes.
|
|
*****************************************************************************/
|
|
ViStatus _VI_FUNC inst_WriteInstrData (ViSession vi, ViConstString writeBuffer)
|
|
{
|
|
return Ivi_WriteInstrData (vi, writeBuffer);
|
|
}
|
|
ViStatus _VI_FUNC inst_ReadInstrData (ViSession vi, ViInt32 numBytes,
|
|
ViChar rdBuf[], ViInt32 *bytesRead)
|
|
{
|
|
return Ivi_ReadInstrData (vi, numBytes, rdBuf, bytesRead);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*-------------------- Utility Functions (Not Exported) ---------------------*
|
|
*****************************************************************************/
|
|
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_IviInit
|
|
* Purpose: This function is called by inst_InitWithOptions
|
|
* or by an IVI class driver. This function initializes the I/O
|
|
* interface, optionally resets the device, optionally performs an
|
|
* ID query, and sends a default setup to the instrument.
|
|
*****************************************************************************/
|
|
static ViStatus inst_IviInit (ViRsrc resourceName, ViBoolean IDQuery,
|
|
ViBoolean reset, ViSession vi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
ViSession io = VI_NULL;
|
|
char config[255];
|
|
char name[255];
|
|
char type[5];
|
|
char location;
|
|
unsigned int baud=9600;
|
|
char bits =8 ;
|
|
char stop=1;
|
|
char parite='N';
|
|
char flux='N';
|
|
char termchar=0;
|
|
/* Add attributes */
|
|
// checkErr( smu_InitAttributes (vi));
|
|
|
|
if (!Ivi_Simulating(vi))
|
|
{
|
|
ViSession rmSession = VI_NULL;
|
|
|
|
/* Open instrument session */
|
|
checkErr( Ivi_GetAttributeViSession (vi, VI_NULL, IVI_ATTR_VISA_RM_SESSION, 0,&rmSession));
|
|
strncpy(type,resourceName,4);
|
|
type[4]=0;
|
|
if(strcmp(type,"ASRL")==0)
|
|
{
|
|
sprintf(config,"%s",strrchr (resourceName,':' ));
|
|
resourceName[strlen(resourceName)-strlen(config)-1]=0;
|
|
sscanf(config,":%d-%c-%c-%c-%c-%c",&baud,&bits,&parite,&stop,&flux,&termchar);
|
|
|
|
bits=bits-48;
|
|
}
|
|
|
|
viCheckErr( viOpen (rmSession, resourceName, VI_NULL, VI_NULL, &io));
|
|
/* Configure VISA Formatted I/O */
|
|
if(strcmp(type,"ASRL")==0)
|
|
{
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_BAUD,baud )); //BAUD
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_DATA_BITS,bits )); //DATA BITS
|
|
switch (parite)
|
|
{
|
|
case 'N':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_PARITY,VI_ASRL_PAR_NONE ));
|
|
break;
|
|
case 'O':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_PARITY,VI_ASRL_PAR_ODD ));
|
|
break;
|
|
case 'E':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_PARITY,VI_ASRL_PAR_EVEN ));
|
|
break;
|
|
case 'M':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_PARITY,VI_ASRL_PAR_MARK ));
|
|
break;
|
|
case 'S':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_PARITY,VI_ASRL_PAR_SPACE ));
|
|
break;
|
|
}
|
|
switch (flux) //FLOW_CNTRL
|
|
{
|
|
case 'N':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_FLOW_CNTRL,VI_ASRL_FLOW_NONE ));
|
|
break;
|
|
case 'X':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_FLOW_CNTRL,VI_ASRL_FLOW_XON_XOFF ));
|
|
break;
|
|
case 'R':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_FLOW_CNTRL,VI_ASRL_FLOW_RTS_CTS ));
|
|
break;
|
|
case 'D':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_FLOW_CNTRL,VI_ASRL_FLOW_DTR_DSR ));
|
|
break;
|
|
}
|
|
|
|
switch (stop)//STOP_BITS
|
|
{
|
|
|
|
case '1':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_STOP_BITS,VI_ASRL_STOP_ONE ));
|
|
break;
|
|
case '5'://1.5
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_STOP_BITS,VI_ASRL_STOP_ONE5 ));
|
|
break;
|
|
case '2':
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_STOP_BITS,VI_ASRL_STOP_TWO ));
|
|
break;
|
|
}
|
|
if(termchar!=0)
|
|
{
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_TERMCHAR,termchar)); //0x0d CR
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_END_IN, VI_ASRL_END_TERMCHAR ));
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_END_OUT, VI_ASRL_END_TERMCHAR ));//terminaison on
|
|
}else
|
|
{
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_END_IN, VI_ASRL_END_NONE ));
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_ASRL_END_OUT, VI_ASRL_END_NONE ));
|
|
}
|
|
}
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_TMO_VALUE, 500 )); //duree time out
|
|
viCheckErr( viSetBuf (io, VI_READ_BUF | VI_WRITE_BUF, 4000));
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_WR_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS));
|
|
viCheckErr( viSetAttribute (io, VI_ATTR_RD_BUF_OPER_MODE, VI_FLUSH_ON_ACCESS));
|
|
}
|
|
/* io session owned by driver now */
|
|
checkErr( Ivi_SetAttributeViSession (vi, VI_NULL, IVI_ATTR_IO_SESSION, 0, io));
|
|
/*- Reset instrument ----------------------------------------------------*/
|
|
// if (reset)
|
|
// checkErr( smu_reset (vi));
|
|
// else /*- Send Default Instrument Setup ---------------------------------*/
|
|
// checkErr( smu_DefaultInstrSetup (vi));
|
|
|
|
// checkErr( smu_CheckStatus (vi));
|
|
|
|
if (IDQuery)
|
|
viCheckWarn( VI_WARN_NSUP_ID_QUERY);
|
|
|
|
if (reset && error == VI_SUCCESS )
|
|
viCheckWarn( VI_WARN_NSUP_RESET);
|
|
|
|
Error:
|
|
if (error < VI_SUCCESS)
|
|
{
|
|
if (!Ivi_Simulating (vi) && io)
|
|
viClose (io);
|
|
}
|
|
return error;
|
|
}
|
|
/*****************************************************************************
|
|
* Function: inst_IviClose
|
|
* Purpose: This function performs all of the drivers clean-up operations
|
|
* except for closing the IVI session. This function is called by
|
|
* inst_close or by an IVI class driver.
|
|
*
|
|
* Note: This function must close the I/O session and set
|
|
* IVI_ATTR_IO_SESSION to 0.
|
|
*****************************************************************************/
|
|
static ViStatus inst_IviClose (ViSession vi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
ViSession io = VI_NULL;
|
|
|
|
/* Do not lock here. The caller manages the lock. */
|
|
|
|
checkErr( Ivi_GetAttributeViSession (vi, VI_NULL, IVI_ATTR_IO_SESSION, 0, &io));
|
|
|
|
Error:
|
|
Ivi_SetAttributeViSession (vi, VI_NULL, IVI_ATTR_IO_SESSION, 0, VI_NULL);
|
|
if(io)
|
|
{
|
|
viClose (io);
|
|
}
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_CheckStatus
|
|
* Purpose: This function checks the status of the instrument to detect
|
|
* whether the instrument has encountered an error. This function
|
|
* is called at the end of most exported driver functions. If the
|
|
* instrument reports an error, this function returns
|
|
* IVI_ERROR_INSTRUMENT_SPECIFIC. The user can set the
|
|
* INST_ATTR_QUERY_INSTRUMENT_STATUS attribute to VI_FALSE to disable this
|
|
* check and increase execution speed.
|
|
*
|
|
* Note: Call this function only when the session is locked.
|
|
*****************************************************************************/
|
|
static ViStatus inst_CheckStatus (ViSession vi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
if (Ivi_QueryInstrStatus (vi) && Ivi_NeedToCheckStatus (vi) && !Ivi_Simulating (vi))
|
|
{
|
|
checkErr( inst_CheckStatusCallback (vi, Ivi_IOSession(vi)));
|
|
checkErr( Ivi_SetNeedToCheckStatus (vi, VI_FALSE));
|
|
}
|
|
|
|
Error:
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_WaitForOPC
|
|
* Purpose: This function waits for the instrument to complete the
|
|
* execution of all pending operations. This function is a
|
|
* wrapper for the WaitForOPCCallback. It can be called from
|
|
* other instrument driver functions.
|
|
*
|
|
* The maxTime parameter specifies the maximum time to wait for
|
|
* operation complete in milliseconds.
|
|
*
|
|
* Note: Call this function only when the session is locked.
|
|
*****************************************************************************/
|
|
static ViStatus inst_WaitForOPC (ViSession vi, ViInt32 maxTime)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
if (!Ivi_Simulating(vi))
|
|
{
|
|
ViInt32 oldOPCTimeout;
|
|
|
|
checkErr( Ivi_GetAttributeViInt32 (vi, VI_NULL, INST_ATTR_OPC_TIMEOUT,
|
|
0, &oldOPCTimeout));
|
|
Ivi_SetAttributeViInt32 (vi, VI_NULL, INST_ATTR_OPC_TIMEOUT,
|
|
0, maxTime);
|
|
|
|
error = inst_WaitForOPCCallback (vi, Ivi_IOSession(vi));
|
|
|
|
Ivi_SetAttributeViInt32 (vi, VI_NULL, INST_ATTR_OPC_TIMEOUT,
|
|
0, oldOPCTimeout);
|
|
viCheckErr( error);
|
|
}
|
|
Error:
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_DefaultInstrSetup
|
|
* Purpose: This function sends a default setup to the instrument. The
|
|
* inst_reset function calls this function. The
|
|
* inst_IviInit function calls this function when the
|
|
* user passes VI_FALSE for the reset parameter. This function is
|
|
* useful for configuring settings that other instrument driver
|
|
* functions require.
|
|
*
|
|
* Note: Call this function only when the session is locked.
|
|
*****************************************************************************/
|
|
static ViStatus inst_DefaultInstrSetup (ViSession vi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
/* Invalidate all attributes */
|
|
checkErr( Ivi_InvalidateAllAttributes (vi));
|
|
|
|
if (!Ivi_Simulating(vi))
|
|
{
|
|
ViSession io = Ivi_IOSession(vi); /* call only when locked */
|
|
|
|
checkErr( Ivi_SetNeedToCheckStatus (vi, VI_TRUE));
|
|
|
|
/*=CHANGE:===============================================================*
|
|
Change the following command string so that it executes the default
|
|
setup for your instrument. The example does the following:
|
|
|
|
*CLS clears the event/status registers
|
|
*ESE 1 sets the standard event status enable register to recognize
|
|
operation complete.
|
|
*SRE 32 sets the service request register to enable a service
|
|
request on operation complete
|
|
|
|
These settings are required for the default implementation of the
|
|
WaitForOPCCallback to work correctly.
|
|
|
|
viCheckErr( viPrintf (io, "*CLS;*ESE 1;*SRE 32"));
|
|
*============================================================END=CHANGE=*/
|
|
|
|
viCheckErr( viPrintf (io, ":HEADERS OFF"));
|
|
}
|
|
Error:
|
|
return error;
|
|
}
|
|
|
|
|
|
/*****************************************************************************
|
|
* Function: ReadToFile and WriteFromFile Functions
|
|
* Purpose: Functions for instrument driver developers to read/write
|
|
* instrument data to/from a file.
|
|
*****************************************************************************/
|
|
static ViStatus inst_ReadToFile (ViSession vi, ViConstString filename,
|
|
ViInt32 maxBytesToRead, ViInt32 fileAction,
|
|
ViInt32 *totalBytesWritten)
|
|
{
|
|
return Ivi_ReadToFile (vi, filename, maxBytesToRead, fileAction, totalBytesWritten);
|
|
}
|
|
static ViStatus inst_WriteFromFile (ViSession vi, ViConstString filename,
|
|
ViInt32 maxBytesToWrite, ViInt32 byteOffset,
|
|
ViInt32 *totalBytesWritten)
|
|
{
|
|
return Ivi_WriteFromFile (vi, filename, maxBytesToWrite, byteOffset, totalBytesWritten);
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*------------------------ Global Session Callbacks -------------------------*
|
|
*****************************************************************************/
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_CheckStatusCallback
|
|
* Purpose: This function queries the instrument to determine if it has
|
|
* encountered an error. If the instrument has encountered an
|
|
* error, this function returns the IVI_ERROR_INSTRUMENT_SPECIFIC
|
|
* error code. This function is called by the
|
|
* inst_CheckStatus utility function. The
|
|
* Ivi_SetAttribute and Ivi_GetAttribute functions invoke this
|
|
* function when the optionFlags parameter includes the
|
|
* IVI_VAL_DIRECT_USER_CALL flag.
|
|
*
|
|
* The user can disable calls to this function by setting the
|
|
* INST_QUERY_INSTRUMENT_STATUS attribute to VI_FALSE. The driver can
|
|
* disable the check status callback for a particular attribute by
|
|
* setting the IVI_VAL_DONT_CHECK_STATUS flag.
|
|
*****************************************************************************/
|
|
static ViStatus _VI_FUNC inst_CheckStatusCallback (ViSession vi, ViSession io)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
|
|
|
|
/* Query instrument status */
|
|
/*=CHANGE:===============================================================*
|
|
Change the *ESR? to the query command that requests the instrument to
|
|
indicate whether it has encountered an error. The following example
|
|
code is based on IEEE 488.2 Common System Commands. Example:
|
|
|
|
ViInt16 esr = 0;
|
|
|
|
viCheckErr( viQueryf (io, "*ESR?", "%hd", &esr));
|
|
if (esr & IEEE_488_2_ERROR_MASK)
|
|
{
|
|
viCheckErr( IVI_ERROR_INSTR_SPECIFIC);
|
|
}
|
|
*============================================================END=CHANGE=*/
|
|
|
|
Error:
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_WaitForOPCCallback
|
|
* Purpose: This function waits until the instrument has finished processing
|
|
* all pending operations. This function is called by the
|
|
* inst_WaitForOPC utility function. The IVI engine invokes
|
|
* this function in the following two cases:
|
|
* - Before invoking the read callback for attributes for which the
|
|
* IVI_VAL_WAIT_FOR_OPC_BEFORE_READS flag is set.
|
|
* - After invoking the write callback for attributes for which the
|
|
* IVI_VAL_WAIT_FOR_OPC_AFTER_WRITES flag is set.
|
|
*****************************************************************************/
|
|
static ViStatus _VI_FUNC inst_WaitForOPCCallback (ViSession vi, ViSession io)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
/*=CHANGE:===============================================================*
|
|
Change this function to wait for operation complete for your specific
|
|
instrument. This example function is based on the IEEE 488.2 Common
|
|
System Commands. This example shows how to use the
|
|
INST_ATTR_OPC_TIMEOUT hidden attribute to control the
|
|
length of time this function waits. This function assumes that the
|
|
instrument does not generate service requests for other reasons. This
|
|
example performs the following operations:
|
|
|
|
- Enables the service request event.
|
|
- Sends a command that forces the instrument to generate a service
|
|
request.
|
|
- Waits for the service request.
|
|
- Cleans up after the service request.
|
|
|
|
ViInt32 opcTimeout;
|
|
ViUInt16 statusByte;
|
|
|
|
checkErr( Ivi_GetAttributeViInt32 (vi, VI_NULL, INST_ATTR_OPC_TIMEOUT,
|
|
0, &opcTimeout));
|
|
|
|
viCheckErr( viEnableEvent (io, VI_EVENT_SERVICE_REQ, VI_QUEUE, VI_NULL));
|
|
|
|
viCheckErr( viPrintf (io, "*OPC"));
|
|
|
|
// wait for SRQ
|
|
viCheckErr( viWaitOnEvent (io, VI_EVENT_SERVICE_REQ, opcTimeout, VI_NULL, VI_NULL));
|
|
viCheckErr( viDisableEvent (io, VI_EVENT_SERVICE_REQ, VI_QUEUE));
|
|
|
|
// clean up after SRQ
|
|
viCheckErr( viBufWrite (io, "*CLS", 4, VI_NULL));
|
|
viCheckErr( viReadSTB (io, &statusByte));
|
|
|
|
Error:
|
|
viDiscardEvents (io, VI_EVENT_SERVICE_REQ, VI_QUEUE);
|
|
*============================================================END=CHANGE=*/
|
|
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*----------------- Attribute Range Tables and Callbacks --------------------*
|
|
*****************************************************************************/
|
|
|
|
/*- INST_ATTR_SPECIFIC_DRIVER_REVISION -*/
|
|
|
|
static ViStatus _VI_FUNC instAttrDriverRevision_ReadCallback (ViSession vi,
|
|
ViSession io,
|
|
ViConstString channelName,
|
|
ViAttr attributeId,
|
|
const ViConstString cacheValue)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
ViChar driverRevision[256];
|
|
|
|
|
|
sprintf (driverRevision,
|
|
"Driver: inst %d.%d, Compiler: %s %3.2f, "
|
|
"Components: IVIEngine %.2f, VISA-Spec %.2f",
|
|
INST_MAJOR_VERSION, INST_MINOR_VERSION,
|
|
IVI_COMPILER_NAME, IVI_COMPILER_VER_NUM,
|
|
IVI_ENGINE_MAJOR_VERSION + IVI_ENGINE_MINOR_VERSION/1000.0,
|
|
Ivi_ConvertVISAVer(VI_SPEC_VERSION));
|
|
|
|
checkErr( Ivi_SetValInStringCallback (vi, attributeId, driverRevision));
|
|
Error:
|
|
return error;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************
|
|
* Function: inst_InitAttributes
|
|
* Purpose: This function adds attributes to the IVI session, initializes
|
|
* instrument attributes, and sets attribute invalidation
|
|
* dependencies.
|
|
*****************************************************************************/
|
|
static ViStatus inst_InitAttributes (ViSession vi)
|
|
{
|
|
ViStatus error = VI_SUCCESS;
|
|
ViInt32 flags = 0;
|
|
/*=CHANGE:=============================================================*
|
|
|
|
NOTE TO THE DEVELOPER: You can add additional parameters to the
|
|
prototype of this function. This is useful when you want to pass
|
|
information from the initialization functions. The Attribute Editor
|
|
in LabWindows/CVI requires that the name of this function be
|
|
inst_InitAttributes.
|
|
|
|
*==========================================================END=CHANGE=*/
|
|
|
|
/*- Initialize instrument attributes --------------------------------*/
|
|
/*=CHANGE:=============================================================*
|
|
NOTE TO THE DEVELOPER: These attributes are obsolete and may not be
|
|
supported in future versions of IVI drivers.
|
|
|
|
If you DO NOT want this driver to be compliant with NI's Ivi Driver
|
|
Toolset 1.1, remove these attribute initalizations.
|
|
|
|
If you DO want this driver to be compliant with NI's IVI Driver Toolset
|
|
1.1, remove the comments around these attribute initalizations.
|
|
|
|
checkErr( Ivi_SetAttributeViInt32 (vi, "", INST_ATTR_SPECIFIC_DRIVER_MAJOR_VERSION,
|
|
0, INST_MAJOR_VERSION));
|
|
checkErr( Ivi_SetAttributeViInt32 (vi, "", INST_ATTR_SPECIFIC_DRIVER_MINOR_VERSION,
|
|
0, INST_MINOR_VERSION));
|
|
checkErr( Ivi_SetAttributeViString (vi, "", INST_ATTR_IO_SESSION_TYPE,
|
|
0, INST_IO_SESSION_TYPE));
|
|
*==========================================================END=CHANGE=*/
|
|
|
|
checkErr( Ivi_SetAttrReadCallbackViString (vi, INST_ATTR_SPECIFIC_DRIVER_REVISION,
|
|
instAttrDriverRevision_ReadCallback));
|
|
checkErr( Ivi_SetAttributeViInt32 (vi, "", INST_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MAJOR_VERSION,
|
|
0, INST_CLASS_SPEC_MAJOR_VERSION));
|
|
checkErr( Ivi_SetAttributeViInt32 (vi, "", INST_ATTR_SPECIFIC_DRIVER_CLASS_SPEC_MINOR_VERSION,
|
|
0, INST_CLASS_SPEC_MINOR_VERSION));
|
|
checkErr( Ivi_SetAttributeViString (vi, "", INST_ATTR_SUPPORTED_INSTRUMENT_MODELS,
|
|
0, INST_SUPPORTED_INSTRUMENT_MODELS));
|
|
|
|
|
|
|
|
/*=CHANGE:===============================================================*
|
|
|
|
Replace the "Instrument Manufacturer" here with the actual manufacturer
|
|
|
|
*============================================================END=CHANGE=*/
|
|
checkErr( Ivi_SetAttributeViString (vi, "", INST_ATTR_INSTRUMENT_MANUFACTURER,
|
|
0, "Instrument Manufacturer"));
|
|
|
|
/*=CHANGE:===============================================================*
|
|
|
|
Replace the "Instrument Model" here with the actual instrument model:
|
|
|
|
*============================================================END=CHANGE=*/
|
|
|
|
checkErr( Ivi_SetAttributeViString (vi, "", INST_ATTR_INSTRUMENT_MODEL,
|
|
0, "Instrument Model"));
|
|
|
|
checkErr( Ivi_SetAttributeViString (vi, "", INST_ATTR_SPECIFIC_DRIVER_VENDOR,
|
|
0, INST_DRIVER_VENDOR));
|
|
checkErr( Ivi_SetAttributeViString (vi, "", INST_ATTR_SPECIFIC_DRIVER_DESCRIPTION,
|
|
0, INST_DRIVER_DESCRIPTION));
|
|
checkErr( Ivi_SetAttributeViAddr (vi, VI_NULL, IVI_ATTR_OPC_CALLBACK, 0,
|
|
inst_WaitForOPCCallback));
|
|
checkErr( Ivi_SetAttributeViAddr (vi, VI_NULL, IVI_ATTR_CHECK_STATUS_CALLBACK, 0,
|
|
inst_CheckStatusCallback));
|
|
|
|
|
|
/*=CHANGE:===============================================================*
|
|
Set the group capabilities attribute, Remove the extension groups
|
|
this driver does not support, and add additional code to dynamically
|
|
determine how the presence of specific instrument options may affect
|
|
this attribute.
|
|
*============================================================END=CHANGE=*/
|
|
|
|
checkErr( Ivi_SetAttributeViString (vi, "", INST_ATTR_GROUP_CAPABILITIES, 0,
|
|
"None"));
|
|
|
|
/*- Add instrument-specific attributes ------------------------------*/
|
|
checkErr( Ivi_AddAttributeViInt32 (vi, INST_ATTR_OPC_TIMEOUT,
|
|
"INST_ATTR_OPC_TIMEOUT",
|
|
5000, IVI_VAL_HIDDEN | IVI_VAL_DONT_CHECK_STATUS,
|
|
VI_NULL, VI_NULL, VI_NULL));
|
|
checkErr( Ivi_AddAttributeViSession (vi,
|
|
INST_ATTR_VISA_RM_SESSION,
|
|
"INST_ATTR_VISA_RM_SESSION",
|
|
VI_NULL,
|
|
IVI_VAL_HIDDEN | IVI_VAL_DONT_CHECK_STATUS,
|
|
VI_NULL, VI_NULL));
|
|
checkErr( Ivi_AddAttributeViAddr (vi, INST_ATTR_OPC_CALLBACK,
|
|
"INST_ATTR_OPC_CALLBACK",
|
|
VI_NULL,
|
|
IVI_VAL_HIDDEN | IVI_VAL_DONT_CHECK_STATUS,
|
|
VI_NULL, VI_NULL));
|
|
checkErr( Ivi_AddAttributeViAddr (vi,
|
|
INST_ATTR_CHECK_STATUS_CALLBACK,
|
|
"INST_ATTR_CHECK_STATUS_CALLBACK",
|
|
VI_NULL,
|
|
IVI_VAL_HIDDEN | IVI_VAL_DONT_CHECK_STATUS,
|
|
VI_NULL, VI_NULL));
|
|
checkErr( Ivi_AddAttributeViAddr (vi,
|
|
INST_ATTR_USER_INTERCHANGE_CHECK_CALLBACK,
|
|
"INST_ATTR_USER_INTERCHANGE_CHECK_CALLBACK",
|
|
VI_NULL,
|
|
IVI_VAL_HIDDEN | IVI_VAL_DONT_CHECK_STATUS,
|
|
VI_NULL, VI_NULL));
|
|
|
|
/*- Setup attribute invalidations -----------------------------------*/
|
|
|
|
/*=CHANGE:===============================================================*
|
|
|
|
Set attribute dependencies by calling the additional
|
|
Ivi_AddAttributeInvalidation functions here. Remove the dependencies
|
|
that do not apply to your instrument by deleting the calls to
|
|
Ivi_AddAttributeInvalidation.
|
|
When you initially add an attribute, it applies to all channels / repeated
|
|
capability instances. If you want it to apply to only a subset, call the
|
|
Ivi_RestrictAttrToChannels or Ivi_RestrictAttrToInstances function.
|
|
|
|
*============================================================END=CHANGE=*/
|
|
|
|
Error:
|
|
return error;
|
|
}
|
|
|
|
/*****************************************************************************
|
|
*------------------- End Instrument Driver Source Code ---------------------*
|
|
*****************************************************************************/
|