6 static int nitems_max_default = (getenv(
"ISISVME_NITEMS_MAX") != NULL ? atoi(getenv(
"ISISVME_NITEMS_MAX")) : 10*1024*1024);
19 throw std::runtime_error(
"VisaAccessLock: invalid thread id");
42 throw std::runtime_error(
"VisaAccessLock: invalid thread id");
79 NIVisa::NIVisa(
DAEstatus& dstatus) :
ISISVME(), m_init_done(false), m_default_rm(VI_NULL), m_block_transfers(false), m_instr_le(VI_NULL), m_instr_be(VI_NULL),
80 m_instr_le_bt(VI_NULL), m_instr_be_bt(VI_NULL), m_instr_backplane(VI_NULL), m_device(
""), m_device_bp(
""), m_trigger_func(NULL), m_trigger_func_arg(NULL)
110 if (status == VI_SUCCESS)
117 std::ostringstream message;
118 message <<
"viOpenDefaultRM(error code=" << status <<
")";
152 viGetAttribute(context, VI_ATTR_JOB_ID, &jobId);
153 viGetAttribute(context, VI_ATTR_STATUS, &vi_status);
170 if (eventType == VI_EVENT_TRIG)
172 viGetAttribute(context, VI_ATTR_RECV_TRIG_ID, &trig_id);
173 vme->
onTrigger(tb.time, tb.millitm, trig_id);
198 std::ostringstream message;
205 if (status != VI_SUCCESS)
207 message <<
"Error opening \"" << device <<
"\"" << std::endl;
218 if (status != VI_SUCCESS)
220 message <<
"Error opening \"" << device <<
"\"" << std::endl;
225 ViUInt16 interface_type;
237 status = viGetAttribute(
m_instr_le, VI_ATTR_INTF_TYPE, &interface_type);
238 if (status == VI_SUCCESS)
240 switch(interface_type)
264 if (status != VI_SUCCESS)
272 if (status != VI_SUCCESS)
277 if (getenv(
"ISISVME_USE_PIO") != NULL)
279 if (status == VI_SUCCESS)
282 status = viSetAttribute(
m_instr_be, VI_ATTR_DMA_ALLOW_EN, VI_FALSE);
283 status = viSetAttribute(
m_instr_be_bt, VI_ATTR_DMA_ALLOW_EN, VI_FALSE);
285 if (status == VI_SUCCESS)
287 status = viSetAttribute(
m_instr_le, VI_ATTR_DMA_ALLOW_EN, VI_FALSE);
288 status = viSetAttribute(
m_instr_le_bt, VI_ATTR_DMA_ALLOW_EN, VI_FALSE);
291 if (getenv(
"ISISVME_TIMEOUT") != NULL)
293 ViUInt32 time_out = atol(getenv(
"ISISVME_TIMEOUT"));
294 if (status == VI_SUCCESS)
297 status = viSetAttribute(
m_instr_be, VI_ATTR_TMO_VALUE, time_out);
298 status = viSetAttribute(
m_instr_be_bt, VI_ATTR_TMO_VALUE, time_out);
300 if (status == VI_SUCCESS)
302 status = viSetAttribute(
m_instr_le, VI_ATTR_TMO_VALUE, time_out);
303 status = viSetAttribute(
m_instr_le_bt, VI_ATTR_TMO_VALUE, time_out);
309 if (status == VI_SUCCESS)
312 status = viSetAttribute (
m_instr_le, 0x3FFF0161, 0x0);
315 if (status == VI_SUCCESS)
317 status = viSetAttribute (
m_instr_be, 0x3FFF0161, 0x0);
321 if (status != VI_SUCCESS)
332 if (viEnableEvent(
m_instr_le, VI_EVENT_IO_COMPLETION, VI_HNDLR, VI_NULL) != VI_SUCCESS)
336 if (viEnableEvent(
m_instr_be, VI_EVENT_IO_COMPLETION, VI_HNDLR, VI_NULL) != VI_SUCCESS)
340 if (viEnableEvent(
m_instr_le_bt, VI_EVENT_IO_COMPLETION, VI_HNDLR, VI_NULL) != VI_SUCCESS)
344 if (viEnableEvent(
m_instr_be_bt, VI_EVENT_IO_COMPLETION, VI_HNDLR, VI_NULL) != VI_SUCCESS)
359 std::ostringstream message;
363 status = viOpen(
m_default_rm, (
char*)device_bp, VI_NULL,
365 if (status != VI_SUCCESS)
367 message <<
"Error opening \"" << device_bp <<
"\"" << std::endl;
372 if (status != VI_SUCCESS)
384 if (status != VI_SUCCESS)
390 if (status != VI_SUCCESS)
402 status = viGetAttribute(
m_instr_backplane, VI_ATTR_VXI_TRIG_SUPPORT, &my_uint32);
403 if (status != VI_SUCCESS)
408 if ( (my_uint32 & (1 << VI_TRIG_ECL0)) == 0)
413 if (status != VI_SUCCESS)
434 status = viLock(
m_instr_le, VI_SHARED_LOCK, 1000 * timeout,
439 status = viLock(
m_instr_le, VI_SHARED_LOCK, 1000 * timeout,
442 if (status == VI_SUCCESS)
466 if (status == VI_SUCCESS)
479 template <
typename F,
typename T>
482 int current_sev = dstatus.
severity();
492 LOGSTR_WARNING(
"retrySingle: address 0x" << std::hex << address << std::dec);
496 stat = (this->*pFunc)(address, data, props, dstatus);
500 if ( !(dstatus >= current_sev) )
507 template <
typename F,
typename T>
511 int current_sev = dstatus.
severity();
520 LOGSTR_WARNING(
"retryBlock: " << nitems <<
" items from address 0x" << std::hex << address << std::dec);
524 stat = (this->*pFunc)(address, data, nitems, props, dstatus);
528 if ( !(dstatus >= current_sev) )
542 return readU16impl(address, data16, props, dstatus);
552 status = viIn16(session, VI_A32_SPACE, address, data16);
553 if (status == VI_SUCCESS)
559 addError(session,
"viIn16", status, address, 1,
"", dstatus);
571 return readU32impl(address, data32, props, dstatus);
581 status = viIn32(session, VI_A32_SPACE, address, data32);
582 if (status == VI_SUCCESS)
588 addError(session,
"viIn32", status, address, 1,
"", dstatus);
617 int nitems_left = nitems;
619 bool error_signalled =
false;
620 while(nitems_left > 0)
622 n = (nitems_left > nitems_max ? nitems_max : nitems_left);
623 status = viMoveIn16(session, VI_A32_SPACE, address, n, data16);
624 if (status != VI_SUCCESS)
626 addError(session,
"viMoveIn16", status, address, n,
"", dstatus);
627 error_signalled =
true;
686 return readBlockU32impl(address, reinterpret_cast<isisU32_t*>(data64), 2 * nitems, props, dstatus);
698 unsigned long k = address;
710 int nitems_left = nitems;
712 bool error_signalled =
false;
715 while(!error_signalled && (nitems_left > 0))
717 n = (nitems_left > nitems_max ? nitems_max : nitems_left);
718 mb = (double)((n * 4) / (1024 * 1024));
722 status = viIn32(session, VI_A32_SPACE, address, data32);
729 status = viMoveAsyncEx(session, VI_A32_SPACE, address, VI_WIDTH_32, VI_LOCAL_SPACE,
730 (ViBusAddress64)data32, VI_WIDTH_32, n, &jobid);
731 if (status == VI_SUCCESS_SYNC)
735 else if (status == VI_SUCCESS)
737 jobid_map_t::iterator it;
759 status = viMoveIn32(session, VI_A32_SPACE, address, n, data32);
763 if (status != VI_SUCCESS)
765 addError(session,
"viMoveIn32", status, address, n,
"", dstatus);
766 error_signalled =
true;
781 for(i=0; i<nitems; i++)
783 d32[i] = (((d32[i]) << 24) & 0xff000000) |
784 (((d32[i]) << 8) & 0x00ff0000) |
785 (((d32[i]) >> 8) & 0x0000ff00) |
786 (((d32[i]) >> 24) & 0x000000ff);
814 status = viOut16(session, VI_A32_SPACE, address, data16);
815 if (status == VI_SUCCESS)
821 addError(session,
"viOut16", status, address, 1,
"", dstatus);
837 status = viOut32(session, VI_A32_SPACE, address, data32);
838 if (status == VI_SUCCESS)
844 addError(session,
"viOut32", status, address, 1,
"", dstatus);
873 int nitems_left = nitems;
875 bool error_signalled =
false;
876 while(nitems_left > 0)
878 n = (nitems_left > nitems_max ? nitems_max : nitems_left);
879 status = viMoveOut16(session, VI_A32_SPACE, address, n, data16);
880 if (status != VI_SUCCESS)
882 addError(session,
"viMoveOut16", status, address, n,
"", dstatus);
883 error_signalled =
true;
912 return writeBlockU32impl(address, reinterpret_cast<isisU32_t*>(data64), 2 * nitems, props, dstatus);
923 unsigned long k = address;
932 int nitems_left = nitems;
934 bool error_signalled =
false;
940 for(i=0; i<nitems; i++)
942 data32_tmp[i] = (((data32[i]) << 24) & 0xff000000) |
943 (((data32[i]) << 8) & 0x00ff0000) |
944 (((data32[i]) >> 8) & 0x0000ff00) |
945 (((data32[i]) >> 24) & 0x000000ff);
949 while(!error_signalled && (nitems_left > 0))
951 n = (nitems_left > nitems_max ? nitems_max : nitems_left);
954 status = viOut32(session, VI_A32_SPACE, address, *data32);
958 status = viMoveOut32(session, VI_A32_SPACE, address, n, data32);
960 if (status != VI_SUCCESS)
962 addError(session,
"viMoveOut32", status, address, n,
"", dstatus);
963 error_signalled =
true;
969 if (data32_tmp != NULL)
991 order = VI_LITTLE_ENDIAN;
995 order = VI_BIG_ENDIAN;
997 status = viSetAttribute(session, VI_ATTR_DEST_BYTE_ORDER, order);
998 if (status == VI_SUCCESS)
1000 status = viSetAttribute(session, VI_ATTR_SRC_BYTE_ORDER, order);
1007 if (status == VI_SUCCESS)
1013 addError(session,
"viSetAttribute(ENDIAN)", status,
"", dstatus);
1022 ViUInt16 priv = VI_BLCK_PRIV;
1025 status = viSetAttribute(session, VI_ATTR_DEST_ACCESS_PRIV, priv);
1026 if (status == VI_SUCCESS)
1028 status = viSetAttribute(session, VI_ATTR_SRC_ACCESS_PRIV, priv);
1030 if (status == VI_SUCCESS)
1036 addError(session,
"viSetAttribute(BLCK_PRIV)", status,
"", dstatus);
1047 ViUInt16 priv = VI_DATA_PRIV;
1050 status = viSetAttribute(session, VI_ATTR_DEST_ACCESS_PRIV, priv);
1051 if (status == VI_SUCCESS)
1053 status = viSetAttribute(session, VI_ATTR_SRC_ACCESS_PRIV, priv);
1055 if (status == VI_SUCCESS)
1061 addError(session,
"viSetAttribute(DATA_PRIV)", status,
"", dstatus);
1072 ViUInt16 priv = mode;
1073 status = viSetAttribute(session, VI_ATTR_DEST_ACCESS_PRIV, priv);
1074 if (status == VI_SUCCESS)
1076 status = viSetAttribute(session, VI_ATTR_SRC_ACCESS_PRIV, priv);
1078 if (status == VI_SUCCESS)
1084 addError(session,
"restoreTransferMode", status,
"", dstatus);
1130 std::ostringstream message;
1132 ViChar descr[VI_FIND_BUFLEN];
1133 ViUInt32 i, numInstrs;
1135 status = viFindRsrc(
m_default_rm,
"?*VXI[0-9]*::?*INSTR?*",
1136 &fList, &numInstrs, descr);
1137 if (status != VI_SUCCESS)
1148 message << descr <<
'\n';
1149 viFindNext(fList, descr);
1164 if (status != VI_SUCCESS)
1173 bool reset_done =
false;
1176 status = viGetAttribute(
m_instr_backplane, VI_ATTR_VXI_VME_SYSFAIL_STATE, &state);
1177 if (status != VI_SUCCESS)
1188 dstatus.
addInfo(
FAC_NIVISA,
"VISA: Waiting for SYSFAIL to be removed from backplane");
1198 std::ostringstream message;
1206 if (status != VI_SUCCESS)
1208 message <<
"viOpen " << name <<
" " << status << std::endl;
1213 status = viIn16(instr, VI_A16_SPACE, 0x4, &data16);
1214 if (status != VI_SUCCESS)
1216 message <<
"viOIn16 " << name <<
" " << status << std::endl;
1220 enableA32 = data16 & (1 << 15);
1223 viOut16(instr, VI_A16_SPACE, 0x4, 0xffff);
1227 viOut16(instr, VI_A16_SPACE, 0x4, 0xfffe);
1229 viIn16(instr, VI_A16_SPACE, 0x4, &data16);
1230 if ((data16 & 0xc) != 0xc)
1232 message <<
"VME reset failed 0x" << std::hex << data16 << std::dec << std::endl;
1236 viOut16(instr, VI_A16_SPACE, 0x4, 0x7ffc | enableA32);
1257 std::ostringstream oss;
1258 oss << message <<
'\n';
1265 unsigned long address,
long nitems,
const std::string& message,
DAEstatus& dstatus)
1267 std::ostringstream oss;
1268 oss << message <<
'\n';
1269 printError(session, func, status, address, nitems, oss);
1277 if (viStatusDesc(session, status, desc) == VI_SUCCESS)
1279 os <<
"NIVISA: Error \"" << desc <<
"\" returned from \"" << func <<
"\"";
1283 os <<
"NIVISA: Unknown Error code " << status <<
" returned from \"" << func <<
"\"";
1289 unsigned long address,
long nitems, std::ostream& os)
1293 if (viStatusDesc(session, status, desc) == VI_SUCCESS)
1295 os <<
"NIVISA: Error \"" << desc <<
"\" (code 0x" << std::hex << status << std::dec <<
") returned from \"" << func <<
"\" "
1296 <<
" while transferring " << nitems <<
" items at VME address 0x"
1297 << std::hex << address << std::dec;
1301 os <<
"NIVISA: Unknown Error code " << status <<
" returned from \"" << func <<
"\"";
1318 return readBlockU32(address, data, nitems, props, status);
1323 return readBlockU64(address, data, nitems, props, status);
1328 status = ViLock(instr, VI_SHARED_LOCK, 15000,
"DAE2VMELock", accessKey);
1332 ViLock(instr, VI_LOCK_EXCLUSIVE, 5000,
"DAE2VMELock", VI_NULL)
1333 ViLock(instr, VI_LOCK_EXCLUSIVE, 5000, VI_NULL, VI_NULL)
NIVisa(DAEstatus &dstatus)
int readU32(unsigned long address, isisU32_t *data32, TransferProps props, DAEstatus &dstatus)
uint32_t TransferProps
combination of TransferProp values
int printError(ViSession session, const char *func, ViStatus status, std::ostream &os)
int readBlock(unsigned long address, isisU32_t *data, long nitems, TransferProps props, DAEstatus &status)
int writeBlockU64impl(unsigned long address, uint64_t *data64, long nitems, TransferProps props, DAEstatus &dstatus)
int readU16impl(unsigned long address, isisU16_t *data16, TransferProps props, DAEstatus &dstatus)
static ViStatus _VI_FUNCH TriggerHandler(ViSession vi, ViEventType eventType, ViEvent context, ViAddr userHandle)
void lockInterface(int timeout, DAEstatus &dstatus)
int addError(ViSession session, const char *func, ViStatus status, const std::string &message, DAEstatus &dstatus)
void * m_trigger_func_arg
ViSession getSession(TransferProps props)
int add(DAEstatus &dstatus, bool clear)
trigger_func_t * m_trigger_func
static int nitems_max_default
int addJobid(ViJobId jobId, ViStatus vi_status)
bool resetBusDevice(const char *name, DAEstatus &dstatus)
int restoreTransferMode(ViSession session, int mode, DAEstatus &dstatus)
CRITICAL_SECTION m_job_critical
int readBlockU16impl(unsigned long address, isisU16_t *data16, long nitems, TransferProps props, DAEstatus &dstatus)
#define LOGSTR_WARNING(__arg)
static const DWORD INVALID_THREAD_ID
int reinit(DAEstatus &dstatus)
int scanBus(DAEstatus &status)
int openBackplane(const char *device_bp, DAEstatus &dstatus)
void unlockInterface(DAEstatus &dstatus)
static const int m_retry_time
milliseconds between retries
int writeBlock(unsigned long address, isisU32_t *data, long nitems, TransferProps props, DAEstatus &status)
int writeU32impl(unsigned long address, isisU32_t data32, TransferProps props, DAEstatus &dstatus)
int open(const char *device, DAEstatus &dstatus)
int readBlockU64impl(unsigned long address, uint64_t *data64, long nitems, TransferProps props, DAEstatus &dstatus)
#define LOGSTR_INFORMATION(__arg)
static bool m_endian_workaround
static void unlockExclusive()
#define LOGSTR_ERROR(__arg)
int disableBlockTransfers(ViSession session, DAEstatus &dstatus)
int unlockDevice(DAEstatus &dstatus)
CRITICAL_SECTION m_visa_critical
int writeBlockU16(unsigned long address, isisU16_t *data16, long nitems, TransferProps props, DAEstatus &dstatus)
int writeBlockU64(unsigned long address, uint64_t *data64, long nitems, TransferProps props, DAEstatus &dstatus)
int writeU16impl(unsigned long address, isisU16_t data16, TransferProps props, DAEstatus &dstatus)
int resetSeverityToAtLeast(int severity)
int readU16noRetry(unsigned long address, isisU16_t *data16, TransferProps props, DAEstatus &dstatus)
int retrySingle(F pFunc, unsigned long address, T data, TransferProps props, DAEstatus &dstatus)
int retryBlock(F pFunc, unsigned long address, T data, long nitems, TransferProps props, DAEstatus &dstatus)
static char * m_visa_lock_name
static Poco::RWLock m_interface_lock
int close(DAEstatus &status)
static const int m_tries
number of times to try a read/write
ViSession m_instr_backplane
int writeU32(unsigned long address, isisU32_t data32, TransferProps props, DAEstatus &dstatus)
int readBlockU16(unsigned long address, isisU16_t *data16, long nitems, TransferProps props, DAEstatus &dstatus)
int enableBlockTransfers(ViSession session, DAEstatus &dstatus)
int lockDevice(int timeout, DAEstatus &dstatus)
int readU16(unsigned long address, isisU16_t *data16, TransferProps props, DAEstatus &dstatus)
int readBlockU32impl(unsigned long address, isisU32_t *data32, long nitems, TransferProps props, DAEstatus &dstatus)
int writeBlockU32(unsigned long address, isisU32_t *data32, long nitems, TransferProps props, DAEstatus &dstatus)
void setLoggerName(const std::string &logger_name)
int writeBlockU32impl(unsigned long address, isisU32_t *data32, long nitems, TransferProps props, DAEstatus &dstatus)
int writeBlockU16impl(unsigned long address, isisU16_t *data16, long nitems, TransferProps props, DAEstatus &dstatus)
int setEndian(ViSession session, bool little_endian, DAEstatus &dstatus)
int addInfo(int facility, const std::string &text)
int resetSeverityToAtMost(int severity)
int readBlockU32(unsigned long address, isisU32_t *data32, long nitems, TransferProps props, DAEstatus &dstatus)
int writeU16(unsigned long address, isisU16_t data16, TransferProps props, DAEstatus &dstatus)
static ViStatus _VI_FUNCH IOEventHandler(ViSession vi, ViEventType eventType, ViEvent context, ViAddr userHandle)
int addInfoVa(int facility, const char *format,...)
int onTrigger(time_t the_secs, unsigned short the_ms, ViInt16 trig_id)
bool resetBus(DAEstatus &status)
int readU32noRetry(unsigned long address, isisU32_t *data32, TransferProps props, DAEstatus &dstatus)
int readU32impl(unsigned long address, isisU32_t *data32, TransferProps props, DAEstatus &dstatus)
static void lockExclusive()
int readBlockU64(unsigned long address, uint64_t *data64, long nitems, TransferProps props, DAEstatus &dstatus)