9 #include <cantProceed.h>
12 #include <epicsAssert.h>
13 #include <epicsExit.h>
14 #include <epicsStdio.h>
15 #include <epicsString.h>
16 #include <epicsThread.h>
17 #include <epicsTime.h>
18 #include <osiUnistd.h>
25 #include "asynDriver.h"
26 #include "asynOctet.h"
27 #include "asynOption.h"
28 #include "asynInterposeCom.h"
29 #include "asynInterposeEos.h"
31 #include <epicsExport.h>
60 static std::string
errMsg(ViSession vi, ViStatus err)
62 char err_msg[1024]={0};
63 viStatusDesc (vi, err, err_msg);
64 return std::string(err_msg);
67 #define VI_CHECK_ERROR(__command, __err) \
70 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize, \
71 "%s: %s %s", driver->resourceName, __command, errMsg(driver->vi, err).c_str()); \
80 const char *key,
char *val,
int valSize)
86 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
92 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
93 "%s getOption - not a serial device", driver->
resourceName);
99 ViStatus err = viGetAttribute(driver->
vi, VI_ATTR_ASRL_FLOW_CNTRL, &flow);
101 if (epicsStrCaseCmp(key,
"baud") == 0) {
102 if ( (err = viGetAttribute(driver->
vi, VI_ATTR_ASRL_BAUD, &viu32)) == VI_SUCCESS ) {
103 l = epicsSnprintf(val, valSize,
"%u", (
unsigned)viu32);
106 else if (epicsStrCaseCmp(key,
"bits") == 0) {
107 if ( (err = viGetAttribute(driver->
vi, VI_ATTR_ASRL_DATA_BITS, &viu16)) == VI_SUCCESS ) {
108 l = epicsSnprintf(val, valSize,
"%u", (
unsigned)viu16);
111 else if (epicsStrCaseCmp(key,
"parity") == 0) {
112 if ( (err = viGetAttribute(driver->
vi, VI_ATTR_ASRL_PARITY, &viu16)) == VI_SUCCESS ) {
114 case VI_ASRL_PAR_NONE:
115 l = epicsSnprintf(val, valSize,
"none");
117 case VI_ASRL_PAR_ODD:
118 l = epicsSnprintf(val, valSize,
"odd");
120 case VI_ASRL_PAR_EVEN:
121 l = epicsSnprintf(val, valSize,
"even");
123 case VI_ASRL_PAR_MARK:
124 l = epicsSnprintf(val, valSize,
"mark");
126 case VI_ASRL_PAR_SPACE:
127 l = epicsSnprintf(val, valSize,
"space");
130 l = epicsSnprintf(val, valSize,
"unknown");
135 else if (epicsStrCaseCmp(key,
"stop") == 0) {
136 if ( (err = viGetAttribute(driver->
vi, VI_ATTR_ASRL_STOP_BITS, &viu16)) == VI_SUCCESS ) {
138 case VI_ASRL_STOP_ONE:
139 l = epicsSnprintf(val, valSize,
"1");
141 case VI_ASRL_STOP_ONE5:
142 l = epicsSnprintf(val, valSize,
"1.5");
144 case VI_ASRL_STOP_TWO:
145 l = epicsSnprintf(val, valSize,
"2");
148 l = epicsSnprintf(val, valSize,
"unknown");
153 else if (epicsStrCaseCmp(key,
"clocal") == 0) {
154 l = epicsSnprintf(val, valSize,
"%c", (flow & VI_ASRL_FLOW_DTR_DSR) ?
'N' :
'Y');
156 else if (epicsStrCaseCmp(key,
"crtscts") == 0) {
157 l = epicsSnprintf(val, valSize,
"%c", (flow & VI_ASRL_FLOW_RTS_CTS) ?
'Y' :
'N');
159 else if (epicsStrCaseCmp(key,
"ixon") == 0) {
160 l = epicsSnprintf(val, valSize,
"%c", (flow & VI_ASRL_FLOW_XON_XOFF) ?
'Y' :
'N');
162 else if (epicsStrCaseCmp(key,
"ixany") == 0) {
163 l = epicsSnprintf(val, valSize,
"%c",
'N');
165 else if (epicsStrCaseCmp(key,
"ixoff") == 0) {
166 l = epicsSnprintf(val, valSize,
"%c", (flow & VI_ASRL_FLOW_XON_XOFF) ?
'Y' :
'N');
178 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
179 "Unsupported key \"%s\"", key);
184 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
185 "Value buffer for key '%s' is too small.", key);
188 asynPrint(driver->
pasynUser, ASYN_TRACEIO_DRIVER,
189 "%s getOption, key=%s, val=%s\n",
198 setOption(
void *drvPvt, asynUser *pasynUser,
const char *key,
const char *val)
204 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
210 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
211 "%s setOption - not a serial device", driver->
resourceName);
214 asynPrint(pasynUser, ASYN_TRACE_FLOW,
215 "%s setOption key %s val %s\n", driver->
portName, key, val);
216 ViUInt16 flow, old_flow;
217 ViStatus err = viGetAttribute(driver->
vi, VI_ATTR_ASRL_FLOW_CNTRL, &flow);
220 if (epicsStrCaseCmp(key,
"baud") == 0) {
222 if(sscanf(val,
"%d", &baud) != 1) {
223 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
227 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_BAUD, baud);
229 else if (epicsStrCaseCmp(key,
"bits") == 0) {
231 if(sscanf(val,
"%d", &bits) != 1) {
232 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
236 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_DATA_BITS, bits);
238 else if (epicsStrCaseCmp(key,
"parity") == 0) {
239 if (epicsStrCaseCmp(val,
"none") == 0) {
240 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_PARITY, VI_ASRL_PAR_NONE);
242 else if (epicsStrCaseCmp(val,
"odd") == 0) {
243 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_PARITY, VI_ASRL_PAR_ODD);
245 else if (epicsStrCaseCmp(val,
"even") == 0) {
246 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_PARITY, VI_ASRL_PAR_EVEN);
248 else if (epicsStrCaseCmp(val,
"mark") == 0) {
249 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_PARITY, VI_ASRL_PAR_MARK);
251 else if (epicsStrCaseCmp(val,
"space") == 0) {
252 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_PARITY, VI_ASRL_PAR_SPACE);
255 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
260 else if (epicsStrCaseCmp(key,
"stop") == 0) {
261 if (epicsStrCaseCmp(val,
"1") == 0) {
262 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_STOP_BITS, VI_ASRL_STOP_ONE);
264 else if (epicsStrCaseCmp(val,
"1.5") == 0) {
265 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_STOP_BITS, VI_ASRL_STOP_ONE5);
267 else if (epicsStrCaseCmp(val,
"2") == 0) {
268 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_STOP_BITS, VI_ASRL_STOP_TWO);
271 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
272 "Invalid number of stop bits.");
276 else if (epicsStrCaseCmp(key,
"clocal") == 0) {
277 if (epicsStrCaseCmp(val,
"Y") == 0) {
278 flow &= ~VI_ASRL_FLOW_DTR_DSR;
280 else if (epicsStrCaseCmp(val,
"N") == 0) {
281 flow |= VI_ASRL_FLOW_DTR_DSR;
284 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
285 "Invalid clocal value.");
289 else if (epicsStrCaseCmp(key,
"crtscts") == 0) {
290 if (epicsStrCaseCmp(val,
"Y") == 0) {
291 flow |= VI_ASRL_FLOW_RTS_CTS;
293 else if (epicsStrCaseCmp(val,
"N") == 0) {
294 flow &= ~VI_ASRL_FLOW_RTS_CTS;
297 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
298 "Invalid crtscts value.");
302 else if ( (epicsStrCaseCmp(key,
"ixon") == 0) || (epicsStrCaseCmp(key,
"ixoff") == 0 ) ) {
303 if (epicsStrCaseCmp(val,
"Y") == 0) {
304 flow |= VI_ASRL_FLOW_XON_XOFF;
306 else if (epicsStrCaseCmp(val,
"N") == 0) {
307 flow &= ~VI_ASRL_FLOW_XON_XOFF;
310 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
311 "Invalid %s value.", key);
315 else if (epicsStrCaseCmp(key,
"ixany") == 0) {
316 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
317 "Option ixany not supported on Windows");
320 else if (epicsStrCaseCmp(key,
"wbuff") == 0) {
322 if(sscanf(val,
"%d", &buflen) != 1) {
323 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
327 err = viSetBuf(driver->
vi, VI_IO_OUT_BUF, buflen);
329 else if (epicsStrCaseCmp(key,
"rbuff") == 0) {
331 if(sscanf(val,
"%d", &buflen) != 1) {
332 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
336 err = viSetBuf(driver->
vi, VI_IO_IN_BUF, buflen);
338 else if (epicsStrCaseCmp(key,
"flush") == 0) {
339 if (epicsStrCaseCmp(val,
"Y") == 0) {
342 else if (epicsStrCaseCmp(val,
"N") == 0) {
346 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
347 "Invalid flush value.");
351 else if (epicsStrCaseCmp(key,
"") != 0) {
352 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
353 "Unsupported key \"%s\"", key);
356 if (err == VI_SUCCESS && flow != old_flow)
358 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_FLOW_CNTRL, flow);
361 asynPrint(driver->
pasynUser, ASYN_TRACEIO_DRIVER,
362 "%s setOption, key=%s, val=%s\n",
373 asynPrint(pasynUser, ASYN_TRACE_FLOW,
374 "Close %s connection %s\n", driver->
resourceName, reason);
376 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
381 if ( (err = viClose(driver->
vi)) != VI_SUCCESS )
383 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
388 driver->
vi = VI_NULL;
389 pasynManager->exceptionDisconnect(pasynUser);
402 fprintf(fp,
" Port %s: %sonnected\n",
408 epicsStrnEscapedFromRaw(termChar,
sizeof(termChar), reinterpret_cast<const char*>(&(driver->
termCharIn)), 1);
412 strncpy(termChar,
"<none>",
sizeof(termChar));
415 fprintf(fp,
" Characters written: %lu\n", driver->
nWriteBytes);
416 fprintf(fp,
" Characters read: %lu\n", driver->
nReadBytes);
417 fprintf(fp,
" write operations: %lu\n", driver->
nWriteCalls);
418 fprintf(fp,
" read operations: %lu\n", driver->
nReadCalls);
419 fprintf(fp,
" Is serial device: %c\n", (driver->
isSerial ?
'Y' :
'N'));
420 fprintf(fp,
" Is GPIB device: %c\n", (driver->
isGPIB ?
'Y' :
'N'));
421 fprintf(fp,
" Device sends EOM: %c\n", (driver->
deviceSendsEOM ?
'Y' :
'N'));
422 fprintf(fp,
" Input term char hint: \"%s\" (0x%x)\n", termChar, (
unsigned)driver->
termCharIn);
423 fprintf(fp,
"Internal read tmo (ms): %d\n", ((
int)driver->
readIntTimeout));
434 status=pasynManager->lockPort(driver->
pasynUser);
435 if(status!=asynSuccess)
436 asynPrint(driver->
pasynUser, ASYN_TRACE_ERROR,
"%s: cleanup locking error\n", driver->
portName);
438 if(status==asynSuccess)
439 pasynManager->unlockPort(driver->
pasynUser);
461 asynPrint(pasynUser, ASYN_TRACE_FLOW,
462 "Open connection to \"%s\" reason: %d\n", driver->
resourceName,
466 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
473 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
480 err = viGetAttribute(driver->
vi, VI_ATTR_INTF_INST_NAME, intf_name);
482 err = viGetAttribute(driver->
vi, VI_ATTR_INTF_TYPE, &intf_type);
485 if (intf_type == VI_INTF_ASRL)
488 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_END_OUT, VI_ASRL_END_NONE);
490 err = viSetAttribute(driver->
vi, VI_ATTR_SEND_END_EN, VI_FALSE);
492 err = viSetAttribute(driver->
vi, VI_ATTR_SUPPRESS_END_EN, VI_TRUE);
499 if (intf_type == VI_INTF_GPIB)
503 err = viSetAttribute(driver->
vi, VI_ATTR_GPIB_READDR_EN, VI_TRUE);
508 err = viSetAttribute(driver->
vi, VI_ATTR_SEND_END_EN, VI_TRUE);
520 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_END_IN, VI_ASRL_END_TERMCHAR);
523 err = viSetAttribute(driver->
vi, VI_ATTR_TERMCHAR, driver->
termCharIn);
525 err = viSetAttribute(driver->
vi, VI_ATTR_TERMCHAR_EN, VI_TRUE);
532 err = viSetAttribute(driver->
vi, VI_ATTR_ASRL_END_IN, VI_ASRL_END_NONE);
535 err = viSetAttribute(driver->
vi, VI_ATTR_TERMCHAR_EN, VI_FALSE);
539 err = viClear(driver->
vi);
550 asynPrint(pasynUser, ASYN_TRACE_FLOW,
551 "Opened connection to \"%s\" (%s) isSerial=%c isGPIB=%c\n", driver->
resourceName,
552 intf_name, (driver->
isSerial ?
'Y' :
'N'), (driver->
isGPIB ?
'Y' :
'N'));
561 asynStatus status = asynSuccess;
564 if (status == asynSuccess)
565 pasynManager->exceptionConnect(pasynUser);
579 static asynStatus
writeIt(
void *drvPvt, asynUser *pasynUser,
580 const char *data,
size_t numchars,
size_t *nbytesTransfered)
583 asynStatus status = asynSuccess;
584 bool timedout =
false;
585 epicsTimeStamp epicsTS1, epicsTS2;
588 asynPrint(pasynUser, ASYN_TRACE_FLOW,
590 asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, numchars,
591 "%s write %lu\n", driver->
resourceName, (
unsigned long)numchars);
592 epicsTimeGetCurrent(&epicsTS1);
593 *nbytesTransfered = 0;
596 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
607 driver->
timeout = pasynUser->timeout;
610 err = viSetAttribute(driver->
vi, VI_ATTR_TMO_VALUE, VI_TMO_INFINITE);
614 err = viSetAttribute(driver->
vi, VI_ATTR_TMO_VALUE, static_cast<int>(driver->
timeout * 1000.0));
617 unsigned long actual = 0;
618 err = viWrite(driver->
vi, (ViBuf)data, static_cast<ViUInt32>(numchars), &actual);
619 if ( err == VI_ERROR_TMO )
623 else if ( err != VI_SUCCESS )
626 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
632 err = viFlush(driver->
vi, VI_IO_OUT_BUF);
633 if ( err == VI_ERROR_TMO )
637 else if ( err != VI_SUCCESS )
640 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
646 *nbytesTransfered = actual;
649 status = asynTimeout;
651 epicsTimeGetCurrent(&epicsTS2);
652 asynPrint(pasynUser, ASYN_TRACE_FLOW,
653 "wrote %lu/%lu chars to %s, return %s.\n", (
unsigned long)*nbytesTransfered, (
unsigned long)numchars,
655 pasynManager->strStatus(status));
656 asynPrint(pasynUser, ASYN_TRACE_FLOW,
"%s Write took %f timeout was %f\n",
657 driver->
resourceName, epicsTimeDiffInSeconds(&epicsTS2, &epicsTS1), pasynUser->timeout);
662 static asynStatus
readIt(
void *drvPvt, asynUser *pasynUser,
663 char *data,
size_t maxchars,
size_t *nbytesTransfered,
int *gotEom)
667 asynStatus status = asynSuccess;
668 epicsTimeStamp epicsTS1, epicsTS2;
669 unsigned long actual = 0, actualex = 0;
673 asynPrint(pasynUser, ASYN_TRACE_FLOW,
675 epicsTimeGetCurrent(&epicsTS1);
676 *nbytesTransfered = 0;
677 if (gotEom) *gotEom = 0;
680 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
686 epicsSnprintf(pasynUser->errorMessage,pasynUser->errorMessageSize,
687 "%s maxchars %d. Why <=0?",driver->
resourceName,(
int)maxchars);
690 driver->
timeout = pasynUser->timeout;
698 status = asynTimeout;
699 epicsTimeGetCurrent(&epicsTS2);
700 asynPrint(pasynUser, ASYN_TRACE_FLOW,
701 "read %lu from %s, return %s.\n", (
unsigned long)*nbytesTransfered,
703 pasynManager->strStatus(status));
704 asynPrint(pasynUser, ASYN_TRACE_FLOW,
"%s Read took %f timeout was %f\n", driver->
resourceName,
705 epicsTimeDiffInSeconds(&epicsTS2, &epicsTS1), pasynUser->timeout);
732 err = viSetAttribute(driver->
vi, VI_ATTR_TMO_VALUE, static_cast<int>(driver->
timeout * 1000.0));
738 err = viRead(driver->
vi, (ViBuf)data, static_cast<ViUInt32>(maxchars), &actual);
744 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
751 err = viRead(driver->
vi, (ViBuf)data, 1, &actual);
757 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
761 if (actual > 0 && err == VI_SUCCESS_MAX_CNT)
768 err = viRead(driver->
vi, reinterpret_cast<ViBuf>(data + actual), static_cast<ViUInt32>(maxchars - actual), &actualex);
769 if (err < 0 && err != VI_ERROR_TMO)
772 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
783 err = VI_WARN_UNKNOWN_STATUS;
792 reason |= ASYN_EOM_END;
796 case VI_SUCCESS_TERM_CHAR:
797 reason |= ASYN_EOM_EOS;
800 case VI_SUCCESS_MAX_CNT:
805 status = asynTimeout;
812 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
819 asynPrintIO(pasynUser, ASYN_TRACEIO_DRIVER, data, actual,
830 *nbytesTransfered = actual;
832 if (actual < (
int) maxchars)
835 reason |= ASYN_EOM_CNT;
836 if (gotEom) *gotEom = reason;
837 epicsTimeGetCurrent(&epicsTS2);
838 asynPrint(pasynUser, ASYN_TRACE_FLOW,
839 "read %lu from %s, return %s.\n", (
unsigned long)*nbytesTransfered,
841 pasynManager->strStatus(status));
842 asynPrint(pasynUser, ASYN_TRACE_FLOW,
"%s Read took %f timeout was %f\n", driver->
resourceName,
843 epicsTimeDiffInSeconds(&epicsTS2, &epicsTS1), pasynUser->timeout);
851 epicsTimeStamp epicsTS1, epicsTS2;
852 epicsTimeGetCurrent(&epicsTS1);
857 epicsSnprintf(pasynUser->errorMessage, pasynUser->errorMessageSize,
864 epicsTimeGetCurrent(&epicsTS2);
865 asynPrint(pasynUser, ASYN_TRACE_FLOW,
"%s flush\n", driver->
resourceName);
866 asynPrint(pasynUser, ASYN_TRACE_FLOW,
"%s flush took %f\n", driver->
resourceName,
867 epicsTimeDiffInSeconds(&epicsTS2, &epicsTS1));
894 const char *resourceName,
895 unsigned int priority,
899 const char* termCharIn,
904 static int firstTime = 1;
909 if (portName == NULL) {
910 printf(
"drvAsynVISAPortConfigure: Port name missing.\n");
913 if (resourceName == NULL) {
914 printf(
"drvAsynVISAPortConfigure: resourceName information missing.\n");
931 driver->
portName = epicsStrDup(portName);
937 if (readIntTmoMs != 0)
939 printf(
"drvAsynVISAPortConfigure: using internal read timeout of %d ms\n", readIntTmoMs);
948 if ( termCharIn != NULL && *termCharIn !=
'\0' && !(strlen(termCharIn) == 1 && *termCharIn ==
'0') )
951 epicsStrnRawFromEscaped(termChar,
sizeof(termChar), termCharIn, strlen(termCharIn));
952 if (strlen(termChar) == 1)
955 printf(
"drvAsynVISAPortConfigure: using term char hint \"%s\" (0x%x)\n", termCharIn, (
unsigned)driver->
termCharIn);
959 printf(
"drvAsynVISAPortConfigure: termChar must be single character - NOT SET\n");
962 if (viOpenDefaultRM(&(driver->
defaultRM)) != VI_SUCCESS)
964 printf(
"drvAsynVISAPortConfigure: viOpenDefaultRM failed for port \"%s\"\n", driver->
portName);
968 driver->
pasynUser = pasynManager->createAsynUser(0,0);
973 driver->
common.interfaceType = asynCommonType;
975 driver->
common.drvPvt = driver;
976 driver->
option.interfaceType = asynOptionType;
978 driver->
option.drvPvt = driver;
980 if (pasynManager->registerPort(driver->
portName,
985 printf(
"drvAsynVISAPortConfigure: Can't register myself.\n");
989 status = pasynManager->registerInterface(driver->
portName,&driver->
common);
990 if(status != asynSuccess) {
991 printf(
"drvAsynVISAPortConfigure: Can't register common.\n");
995 status = pasynManager->registerInterface(driver->
portName,&driver->
option);
996 if(status != asynSuccess) {
997 printf(
"drvAsynVISAPortConfigure: Can't register option.\n");
1001 driver->
octet.interfaceType = asynOctetType;
1003 driver->
octet.drvPvt = driver;
1004 status = pasynOctetBase->initialize(driver->
portName,&driver->
octet,
1005 (noProcessEos ? 0 : 1),(noProcessEos ? 0 : 1),1);
1006 if(status != asynSuccess) {
1007 printf(
"drvAsynVISAPortConfigure: Can't register octet.\n");
1012 if(status != asynSuccess) {
1013 printf(
"drvAsynVISAPortConfigure: connectDevice failed %s\n",driver->
pasynUser->errorMessage);
1072 args[4].ival, args[5].ival, args[6].sval, args[7].ival);
1081 static int firstTime = 1;
unsigned long nWriteCalls
number of written calls to this resource
static void visaCleanup(void *arg)
static struct asynCommon asynCommonMethods
static asynStatus writeIt(void *drvPvt, asynUser *pasynUser, const char *data, size_t numchars, size_t *nbytesTransfered)
write values to device
bool flush_on_write
use viFlush to flush output buffer every write
ASYN driver for National Instruments VISA.
static struct asynOption asynOptionMethods
ViSession vi
VISA session handle.
bool deviceSendsEOM
Indicates that the device signals an "end of message".
double timeout
requested timeout for current operation
unsigned long nReadBytes
number of bytes read from this resource name
static asynStatus closeConnection(asynUser *pasynUser, visaDriver_t *driver, const char *reason)
close a VISA session
static const iocshArg drvAsynVISAPortConfigureArg4
Should the driver interpose layer be called for EOS (termination) character processing (0=yes) If you...
static const iocshArg drvAsynVISAPortConfigureArg3
Should the driver automatically connect to the device (0=yes)
unsigned long nReadCalls
number of read calls from this resource name
bool connected
are we currently connected
static asynStatus flushIt(void *drvPvt, asynUser *pasynUser)
flush device
static asynStatus readIt(void *drvPvt, asynUser *pasynUser, char *data, size_t maxchars, size_t *nbytesTransfered, int *gotEom)
read values from device
char * resourceName
VISA resource name session connected to.
static asynStatus getOption(void *drvPvt, asynUser *pasynUser, const char *key, char *val, int valSize)
asynOption interface - get options
static asynStatus asynCommonConnect(void *drvPvt, asynUser *pasynUser)
static const iocshArg drvAsynVISAPortConfigureArg7
Indicates that the device signals an "end of message".
static void drvAsynVISAPortConfigureCallFunc(const iocshArgBuf *args)
static asynStatus asynCommonDisconnect(void *drvPvt, asynUser *pasynUser)
ViUInt8 termCharIn
read termination character, this is purely to improve read efficiency and is independent of any chara...
static const iocshArg drvAsynVISAPortConfigureArg0
A name for the asyn driver instance we will create e.g. "L0".
static const iocshArg drvAsynVISAPortConfigureArg2
Driver priority.
#define VI_CHECK_ERROR(__command, __err)
static std::string errMsg(ViSession vi, ViStatus err)
translate VISA error code to readable string
char * portName
asyn port name
unsigned long nWriteBytes
number of bytes written to this resource
static const iocshArg drvAsynVISAPortConfigureArg5
internal read timeout (ms) used instead of a zero timeout immediate read.
epicsShareFunc int drvAsynVISAPortConfigure(const char *portName, const char *resourceName, unsigned int priority, int noAutoConnect, int noProcessEos, int readIntTmoMs, const char *termCharIn, int deviceSendsEOM)
Create a VISA device.
static const iocshArg drvAsynVISAPortConfigureArg1
VISA resource name to connect to e.g. "GPIB0::3::INSTR" or "COM10".
driver private data structure
static const iocshFuncDef drvAsynVISAPortConfigureFuncDef
bool isGPIB
are we a GPIB device?
static void asynCommonReport(void *drvPvt, FILE *fp, int details)
asynCommon interface - Report link parameters
static void driverCleanup(visaDriver_t *driver)
bool isSerial
are we an RS232 style serial device?
static asynOctet asynOctetMethods
static const iocshArg drvAsynVISAPortConfigureArg6
read termination character, this is purely to improve read efficiency and is independent of any chara...
epicsExportRegistrar(drvAsynVISAPortConfigureRegister)
int readIntTimeout
internal read timeout (ms) used instead of a zero timeout immediate read.
static void drvAsynVISAPortConfigureRegister(void)
static asynStatus setOption(void *drvPvt, asynUser *pasynUser, const char *key, const char *val)
asynOption interface - set options
static asynStatus connectIt(void *drvPvt, asynUser *pasynUser)
create a link
static const iocshArg * drvAsynVISAPortConfigureArgs[]