1# -*- coding: utf-8 -*-
2"""Defines VPP 4.3.2 wrapping functions using ctypes, adding signatures to the library.
3
4This file is part of PyVISA.
5
6:copyright: 2014-2020 by PyVISA Authors, see AUTHORS for more details.
7:license: MIT, see LICENSE for more details.
8
9"""
10import warnings
11from contextlib import contextmanager
12from ctypes import (
13    POINTER,
14    byref,
15    c_double,
16    c_long,
17    c_void_p,
18    c_wchar_p,
19    create_string_buffer,
20)
21from functools import update_wrapper
22from threading import Lock
23from typing import Any, Callable, Optional, Tuple
24
25from pyvisa import attributes, constants, ctwrapper, typing
26from pyvisa.highlevel import ResourceInfo
27
28from . import types
29from .types import (
30    FUNCTYPE,
31    ViAccessMode,
32    ViAChar,
33    ViAddr,
34    ViAttr,
35    ViAttrState,
36    ViAUInt8,
37    ViAUInt16,
38    ViAUInt32,
39    ViAUInt64,
40    ViBoolean,
41    ViBuf,
42    ViBusAddress,
43    ViBusAddress64,
44    ViBusSize,
45    ViEvent,
46    ViEventFilter,
47    ViEventType,
48    ViFindList,
49    ViHndlr,
50    ViInt16,
51    ViJobId,
52    ViKeyId,
53    ViObject,
54    ViPAddr,
55    ViPBuf,
56    ViPBusAddress,
57    ViPEvent,
58    ViPEventType,
59    ViPFindList,
60    ViPJobId,
61    ViPSession,
62    ViPUInt8,
63    ViPUInt16,
64    ViPUInt32,
65    ViPUInt64,
66    ViRsrc,
67    ViSession,
68    ViStatus,
69    ViString,
70    ViUInt8,
71    ViUInt16,
72    ViUInt32,
73    ViUInt64,
74    buffer_to_text,
75)
76
77visa_functions = [
78    "assert_interrupt_signal",
79    "assert_trigger",
80    "assert_utility_signal",
81    "buffer_read",
82    "buffer_write",
83    "clear",
84    "close",
85    "disable_event",
86    "discard_events",
87    "enable_event",
88    "_find_next",
89    "_find_resources",
90    "flush",
91    "get_attribute",
92    "gpib_command",
93    "gpib_control_atn",
94    "gpib_control_ren",
95    "gpib_pass_control",
96    "gpib_send_ifc",
97    "in_16",
98    "in_32",
99    "in_8",
100    "install_handler",
101    "lock",
102    "map_address",
103    "map_trigger",
104    "memory_allocation",
105    "memory_free",
106    "move",
107    "move_asynchronously",
108    "move_in_16",
109    "move_in_32",
110    "move_in_8",
111    "move_out_16",
112    "move_out_32",
113    "move_out_8",
114    "open",
115    "open_default_resource_manager",
116    "out_16",
117    "out_32",
118    "out_8",
119    "parse_resource",
120    "parse_resource_extended",
121    "peek_16",
122    "peek_32",
123    "peek_8",
124    "poke_16",
125    "poke_32",
126    "poke_8",
127    "read",
128    "read_to_file",
129    "read_stb",
130    "set_attribute",
131    "set_buffer",
132    "status_description",
133    "terminate",
134    "uninstall_handler",
135    "unlock",
136    "unmap_address",
137    "unmap_trigger",
138    "usb_control_in",
139    "usb_control_out",
140    "vxi_command_query",
141    "wait_on_event",
142    "write",
143    "write_asynchronously",
144    "write_from_file",
145    "in_64",
146    "move_in_64",
147    "out_64",
148    "move_out_64",
149    "poke_64",
150    "peek_64",
151]
152
153__all__ = ["visa_functions", "set_signatures"] + visa_functions
154
155VI_SPEC_VERSION = 0x00300000
156
157#: Global lock to ensure that we cannot have one thread change the type while
158#: another is trying to interact with VISA
159ViHndlr_lock = Lock()
160
161
162@contextmanager
163def set_user_handle_type(library, user_handle: Any):
164    """Set the type of the user handle to install and uninstall handler signature.
165
166    Parameters
167    ----------
168    library :
169        The visa library wrapped by ctypes.
170    user_handle :
171        User handle used when registering an event handler. Use None for a void_p.
172
173    """
174    with ViHndlr_lock:
175        # Actually, it's not necessary to change ViHndlr *globally*.  However,
176        # I don't want to break symmetry too much with all the other VPP43
177        # routines.
178        global ViHndlr
179
180        if user_handle is None:
181            user_handle_p = c_void_p
182        else:
183            user_handle_p = POINTER(type(user_handle))  # type: ignore
184
185        ViHndlr = FUNCTYPE(ViStatus, ViSession, ViEventType, ViEvent, user_handle_p)
186        library.viInstallHandler.argtypes = [
187            ViSession,
188            ViEventType,
189            ViHndlr,
190            user_handle_p,
191        ]
192        library.viUninstallHandler.argtypes = [
193            ViSession,
194            ViEventType,
195            ViHndlr,
196            user_handle_p,
197        ]
198        yield
199
200
201def set_signatures(
202    library, errcheck: Optional[Callable[[int, Callable, tuple], int]] = None
203):
204    """Set the signatures of most visa functions in the library.
205
206    All instrumentation related functions are specified here.
207
208    Parameters
209    ----------
210    library : ctypes.WinDLL or ctypes.CDLL
211        The visa library wrapped by ctypes.
212    errcheck : Optional[Callable[[int, Callable, tuple], int]]
213        Error checking callable used for visa functions that return ViStatus.
214        It should be take three arguments (result, func, arguments).
215        See errcheck in ctypes.
216
217    """
218    # Somehow hasattr(library, '_functions') segfaults in cygwin (See #131)
219    if "_functions" not in dir(library):
220        library._functions = []
221        library._functions_failed = []
222
223    def _applier(restype, errcheck_):
224        def _internal(function_name, argtypes, required=False):
225            try:
226                set_signature(library, function_name, argtypes, restype, errcheck_)
227                library._functions.append(function_name)
228            except AttributeError:
229                library._functions_failed.append(function_name)
230                if required:
231                    raise
232
233        return _internal
234
235    # Visa functions with ViStatus return code
236    apply = _applier(ViStatus, errcheck)
237    apply("viAssertIntrSignal", [ViSession, ViInt16, ViUInt32])
238    apply("viAssertTrigger", [ViSession, ViUInt16])
239    apply("viAssertUtilSignal", [ViSession, ViUInt16])
240    apply("viBufRead", [ViSession, ViPBuf, ViUInt32, ViPUInt32])
241    apply("viBufWrite", [ViSession, ViBuf, ViUInt32, ViPUInt32])
242    apply("viClear", [ViSession])
243    apply("viClose", [ViObject])
244    apply("viDisableEvent", [ViSession, ViEventType, ViUInt16])
245    apply("viDiscardEvents", [ViSession, ViEventType, ViUInt16])
246    apply("viEnableEvent", [ViSession, ViEventType, ViUInt16, ViEventFilter])
247    apply("viFindNext", [ViSession, ViAChar])
248    apply("viFindRsrc", [ViSession, ViString, ViPFindList, ViPUInt32, ViAChar])
249    apply("viFlush", [ViSession, ViUInt16])
250    apply("viGetAttribute", [ViObject, ViAttr, c_void_p])
251    apply("viGpibCommand", [ViSession, ViBuf, ViUInt32, ViPUInt32])
252    apply("viGpibControlATN", [ViSession, ViUInt16])
253    apply("viGpibControlREN", [ViSession, ViUInt16])
254    apply("viGpibPassControl", [ViSession, ViUInt16, ViUInt16])
255    apply("viGpibSendIFC", [ViSession])
256
257    apply("viIn8", [ViSession, ViUInt16, ViBusAddress, ViPUInt8])
258    apply("viIn16", [ViSession, ViUInt16, ViBusAddress, ViPUInt16])
259    apply("viIn32", [ViSession, ViUInt16, ViBusAddress, ViPUInt32])
260    apply("viIn64", [ViSession, ViUInt16, ViBusAddress, ViPUInt64])
261
262    apply("viIn8Ex", [ViSession, ViUInt16, ViBusAddress64, ViPUInt8])
263    apply("viIn16Ex", [ViSession, ViUInt16, ViBusAddress64, ViPUInt16])
264    apply("viIn32Ex", [ViSession, ViUInt16, ViBusAddress64, ViPUInt32])
265    apply("viIn64Ex", [ViSession, ViUInt16, ViBusAddress64, ViPUInt64])
266
267    apply("viInstallHandler", [ViSession, ViEventType, ViHndlr, ViAddr])
268    apply("viLock", [ViSession, ViAccessMode, ViUInt32, ViKeyId, ViAChar])
269    apply(
270        "viMapAddress",
271        [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViBoolean, ViAddr, ViPAddr],
272    )
273    apply("viMapTrigger", [ViSession, ViInt16, ViInt16, ViUInt16])
274    apply("viMemAlloc", [ViSession, ViBusSize, ViPBusAddress])
275    apply("viMemFree", [ViSession, ViBusAddress])
276    apply(
277        "viMove",
278        [
279            ViSession,
280            ViUInt16,
281            ViBusAddress,
282            ViUInt16,
283            ViUInt16,
284            ViBusAddress,
285            ViUInt16,
286            ViBusSize,
287        ],
288    )
289    apply(
290        "viMoveAsync",
291        [
292            ViSession,
293            ViUInt16,
294            ViBusAddress,
295            ViUInt16,
296            ViUInt16,
297            ViBusAddress,
298            ViUInt16,
299            ViBusSize,
300            ViPJobId,
301        ],
302    )
303
304    apply("viMoveIn8", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt8])
305    apply("viMoveIn16", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt16])
306    apply("viMoveIn32", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt32])
307    apply("viMoveIn64", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt64])
308
309    apply("viMoveIn8Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt8])
310    apply("viMoveIn16Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt16])
311    apply("viMoveIn32Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt32])
312    apply("viMoveIn64Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt64])
313
314    apply("viMoveOut8", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt8])
315    apply("viMoveOut16", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt16])
316    apply("viMoveOut32", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt32])
317    apply("viMoveOut64", [ViSession, ViUInt16, ViBusAddress, ViBusSize, ViAUInt64])
318
319    apply("viMoveOut8Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt8])
320    apply("viMoveOut16Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt16])
321    apply("viMoveOut32Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt32])
322    apply("viMoveOut64Ex", [ViSession, ViUInt16, ViBusAddress64, ViBusSize, ViAUInt64])
323
324    apply(
325        "viOpen", [ViSession, ViRsrc, ViAccessMode, ViUInt32, ViPSession], required=True
326    )
327
328    apply("viOpenDefaultRM", [ViPSession], required=True)
329
330    apply("viOut8", [ViSession, ViUInt16, ViBusAddress, ViUInt8])
331    apply("viOut16", [ViSession, ViUInt16, ViBusAddress, ViUInt16])
332    apply("viOut32", [ViSession, ViUInt16, ViBusAddress, ViUInt32])
333    apply("viOut64", [ViSession, ViUInt16, ViBusAddress, ViUInt64])
334
335    apply("viOut8Ex", [ViSession, ViUInt16, ViBusAddress64, ViUInt8])
336    apply("viOut16Ex", [ViSession, ViUInt16, ViBusAddress64, ViUInt16])
337    apply("viOut32Ex", [ViSession, ViUInt16, ViBusAddress64, ViUInt32])
338    apply("viOut64Ex", [ViSession, ViUInt16, ViBusAddress64, ViUInt64])
339
340    apply("viParseRsrc", [ViSession, ViRsrc, ViPUInt16, ViPUInt16])
341    apply(
342        "viParseRsrcEx",
343        [ViSession, ViRsrc, ViPUInt16, ViPUInt16, ViAChar, ViAChar, ViAChar],
344    )
345
346    apply("viRead", [ViSession, ViPBuf, ViUInt32, ViPUInt32])
347    apply("viReadAsync", [ViSession, ViPBuf, ViUInt32, ViPJobId])
348    apply("viReadSTB", [ViSession, ViPUInt16])
349    apply("viReadToFile", [ViSession, ViString, ViUInt32, ViPUInt32])
350
351    apply("viSetAttribute", [ViObject, ViAttr, ViAttrState])
352    apply("viSetBuf", [ViSession, ViUInt16, ViUInt32])
353
354    apply("viStatusDesc", [ViObject, ViStatus, ViAChar])
355    apply("viTerminate", [ViSession, ViUInt16, ViJobId])
356    apply("viUninstallHandler", [ViSession, ViEventType, ViHndlr, ViAddr])
357    apply("viUnlock", [ViSession])
358    apply("viUnmapAddress", [ViSession])
359    apply("viUnmapTrigger", [ViSession, ViInt16, ViInt16])
360    apply(
361        "viUsbControlIn",
362        [ViSession, ViInt16, ViInt16, ViUInt16, ViUInt16, ViUInt16, ViPBuf, ViPUInt16],
363    )
364    apply(
365        "viUsbControlOut",
366        [ViSession, ViInt16, ViInt16, ViUInt16, ViUInt16, ViUInt16, ViPBuf],
367    )
368
369    # The following "V" routines are *not* implemented in PyVISA, and will
370    # never be: viVPrintf, viVQueryf, viVScanf, viVSPrintf, viVSScanf
371
372    apply("viVxiCommandQuery", [ViSession, ViUInt16, ViUInt32, ViPUInt32])
373    apply("viWaitOnEvent", [ViSession, ViEventType, ViUInt32, ViPEventType, ViPEvent])
374    apply("viWrite", [ViSession, ViBuf, ViUInt32, ViPUInt32])
375    apply("viWriteAsync", [ViSession, ViBuf, ViUInt32, ViPJobId])
376    apply("viWriteFromFile", [ViSession, ViString, ViUInt32, ViPUInt32])
377
378    # Functions that return void.
379    apply = _applier(None, None)
380    apply("viPeek8", [ViSession, ViAddr, ViPUInt8])
381    apply("viPeek16", [ViSession, ViAddr, ViPUInt16])
382    apply("viPeek32", [ViSession, ViAddr, ViPUInt32])
383    apply("viPeek64", [ViSession, ViAddr, ViPUInt64])
384
385    apply("viPoke8", [ViSession, ViAddr, ViUInt8])
386    apply("viPoke16", [ViSession, ViAddr, ViUInt16])
387    apply("viPoke32", [ViSession, ViAddr, ViUInt32])
388    apply("viPoke64", [ViSession, ViAddr, ViUInt64])
389
390
391def set_signature(
392    library,
393    function_name: str,
394    argtypes: tuple,
395    restype,
396    errcheck: Optional[Callable[[int, Callable, tuple], int]],
397):
398    """Set the signature of single function in a library.
399
400    Parameters
401    ----------
402    library : ctypes.WinDLL or ctypes.CDLL
403        ctypes wrapped library.
404    function_name : str
405        Name of the function as appears in the header file.
406    argtypes : tuple
407        ctypes types to specify the argument types that the function accepts.
408    restype :
409        A ctypes type to specify the result type of the foreign function.
410        Use None for void, a function not returning anything.
411    errcheck : Optional[Callable[[int, Callable, tuple], int]]
412        Error checking callable used for visa functions that return ViStatus.
413        It should be take three arguments (result, func, arguments).
414        See errcheck in ctypes.
415
416    """
417
418    func = getattr(library, function_name)
419    func.argtypes = argtypes
420    if restype is not None:
421        func.restype = restype
422    if errcheck is not None:
423        func.errcheck = errcheck
424
425
426# The VPP-4.3.2 routines
427
428# Usually, there is more than one way to pass parameters to ctypes calls.  The
429# ctypes policy used in this code goes as follows:
430#
431# * Null pointers are passed as "None" rather than "0".  This is a little bit
432#   unfortunate, since the VPP specification calls this "VI_NULL", but I can't
433#   use "VI_NULL" since it's an integer and may not be compatible with a
434#   pointer type (don't know whether this is really dangerous).
435#
436# * Strings must have been created with "create_string_buffer" and are passed
437#   without any further conversion; they stand in the parameter list as is.
438#   The same applies to pseudo-string types as ViRsrc or VuBuf.  Their Pythonic
439#   counterpats are strings as well.
440#
441# * All other types are explicitly cast using the types defined by ctypes'
442#   "restype".
443#
444# Further notes:
445#
446# * The following Python routines take and give handles as ctypes objects.
447#   Since the user shouldn't be interested in handle values anyway, I see no
448#   point in converting them to Python strings or integers.
449#
450# * All other parameters are natural Python types, i.e. strings (may contain
451#   binary data) and integers.  The same is true for return values.
452#
453# * The original VPP function signatures cannot be realised in Python, at least
454#   not in a sensible way, because a) Python has no real call-by-reference, and
455#   b) Python allows for more elegant solutions, e.g. using len(buffer) instead
456#   of a separate "count" parameter, or using tuples as return values.
457#
458#   Therefore, all function signatures have been carefully adjusted.  I think
459#   this is okay, since the original standard must be adopted to at least C and
460#   Visual Basic anyway, with slight modifications.  I also made the function
461#   names and parameters more legible, but in a way that it's perfectly clear
462#   which original function is meant.
463#
464#   The important thing is that the semantics of functions and parameters are
465#   totally intact, and the inner order of parameters, too.  There is a 1:1
466#   mapping.
467
468
469def assert_interrupt_signal(library, session, mode, status_id):
470    """Asserts the specified interrupt or signal.
471
472    Corresponds to viAssertIntrSignal function of the VISA library.
473
474    Parameters
475    ----------
476    library : ctypes.WinDLL or ctypes.CDLL
477        ctypes wrapped library.
478    session : VISASession
479        Unique logical identifier to a session.
480    mode : constants.AssertSignalInterrupt
481        How to assert the interrupt.
482    status_id : int
483        Status value to be presented during an interrupt acknowledge cycle.
484
485    Returns
486    -------
487    constants.StatusCode
488        Return value of the library call.
489
490    """
491    return library.viAssertIntrSignal(session, mode, status_id)
492
493
494def assert_trigger(library, session, protocol):
495    """Assert software or hardware trigger.
496
497    Corresponds to viAssertTrigger function of the VISA library.
498
499    Parameters
500    ----------
501    library : ctypes.WinDLL or ctypes.CDLL
502        ctypes wrapped library.
503    session : VISASession
504        Unique logical identifier to a session.
505    protocol : constants.TriggerProtocol
506        Trigger protocol to use during assertion.
507
508    Returns
509    -------
510    constants.StatusCode
511        Return value of the library call.
512
513    """
514    return library.viAssertTrigger(session, protocol)
515
516
517def assert_utility_signal(library, session, line):
518    """Assert or deassert the specified utility bus signal.
519
520    Corresponds to viAssertUtilSignal function of the VISA library.
521
522    Parameters
523    ----------
524    library : ctypes.WinDLL or ctypes.CDLL
525        ctypes wrapped library.
526    session : VISASession
527        Unique logical identifier to a session.
528    line : constants.UtilityBusSignal
529        Specifies the utility bus signal to assert.
530
531    Returns
532    -------
533    constants.StatusCode
534        Return value of the library call.
535
536    """
537    return library.viAssertUtilSignal(session, line)
538
539
540def buffer_read(library, session, count):
541    """Reads data through the use of a formatted I/O read buffer.
542
543    The data can be read from a device or an interface.
544
545    Corresponds to viBufRead function of the VISA library.
546
547    Parameters
548    ----------
549    library : ctypes.WinDLL or ctypes.CDLL
550        ctypes wrapped library.
551    session : VISASession
552        Unique logical identifier to a session.
553    count : int
554        Number of bytes to be read.
555
556    Returns
557    -------
558    dbytes
559        Data read
560    constants.StatusCode
561        Return value of the library call.
562
563    """
564    buffer = create_string_buffer(count)
565    return_count = ViUInt32()
566    ret = library.viBufRead(session, buffer, count, byref(return_count))
567    return buffer.raw[: return_count.value], ret
568
569
570def buffer_write(library, session, data):
571    """Writes data to a formatted I/O write buffer synchronously.
572
573    Corresponds to viBufWrite function of the VISA library.
574
575    Parameters
576    ----------
577    library : ctypes.WinDLL or ctypes.CDLL
578        ctypes wrapped library.
579    session : VISASession
580        Unique logical identifier to a session.
581    data : bytes
582        Data to be written.
583
584    Returns
585    -------
586    int
587        number of written bytes
588    constants.StatusCode
589        return value of the library call.
590
591    """
592    return_count = ViUInt32()
593    # [ViSession, ViBuf, ViUInt32, ViPUInt32]
594    ret = library.viBufWrite(session, data, len(data), byref(return_count))
595    return return_count.value, ret
596
597
598def clear(library, session):
599    """Clears a device.
600
601    Corresponds to viClear function of the VISA library.
602
603    Parameters
604    ----------
605    library : ctypes.WinDLL or ctypes.CDLL
606        ctypes wrapped library.
607    session : VISASession
608        Unique logical identifier to a session.
609
610    Returns
611    -------
612    constants.StatusCode
613        Return value of the library call.
614
615    """
616    return library.viClear(session)
617
618
619def close(library, session):
620    """Closes the specified session, event, or find list.
621
622    Corresponds to viClose function of the VISA library.
623
624    Parameters
625    ---------
626    library : ctypes.WinDLL or ctypes.CDLL
627        ctypes wrapped library.
628    session : Union[VISASession, VISAEventContext, VISARMSession]
629        Unique logical identifier to a session, event, resource manager.
630
631    Returns
632    -------
633    constants.StatusCode
634        Return value of the library call.
635
636    """
637    return library.viClose(session)
638
639
640def disable_event(library, session, event_type, mechanism):
641    """Disable notification for an event type(s) via the specified mechanism(s).
642
643    Corresponds to viDisableEvent function of the VISA library.
644
645    Parameters
646    ----------
647    library : ctypes.WinDLL or ctypes.CDLL
648        ctypes wrapped library.
649    session : VISASession
650        Unique logical identifier to a session.
651    event_type : constants.EventType
652        Event type.
653    mechanism : constants.EventMechanism
654        Event handling mechanisms to be disabled.
655
656    Returns
657    -------
658    constants.StatusCode
659        Return value of the library call.
660
661    """
662    return library.viDisableEvent(session, event_type, mechanism)
663
664
665def discard_events(library, session, event_type, mechanism):
666    """Discard event occurrences for a given type and mechanisms in a session.
667
668    Corresponds to viDiscardEvents function of the VISA library.
669
670    Parameters
671    ----------
672    library : ctypes.WinDLL or ctypes.CDLL
673        ctypes wrapped library.
674    session : VISASession
675        Unique logical identifier to a session.
676    event_type : constans.EventType
677        Logical event identifier.
678    mechanism : constants.EventMechanism
679        Specifies event handling mechanisms to be discarded.
680
681    Returns
682    -------
683    constants.StatusCode
684        Return value of the library call.
685
686    """
687    return library.viDiscardEvents(session, event_type, mechanism)
688
689
690def enable_event(library, session, event_type, mechanism, context=None):
691    """Enable event occurrences for specified event types and mechanisms in a session.
692
693    Corresponds to viEnableEvent function of the VISA library.
694
695    Parameters
696    ----------
697    library : ctypes.WinDLL or ctypes.CDLL
698        ctypes wrapped library.
699    session : VISASession
700        Unique logical identifier to a session.
701    event_type : constants.EventType
702        Logical event identifier.
703    mechanism : constants.EventMechanism
704        Specifies event handling mechanisms to be enabled.
705    context : None, optional
706        Unused parameter...
707
708    Returns
709    -------
710    constants.StatusCode
711        Return value of the library call.
712
713    """
714    if context is None:
715        context = constants.VI_NULL
716    elif context != constants.VI_NULL:
717        warnings.warn("In enable_event, context will be set VI_NULL.")
718        context = constants.VI_NULL  # according to spec VPP-4.3, section 3.7.3.1
719    return library.viEnableEvent(session, event_type, mechanism, context)
720
721
722def _find_next(library, find_list: ViFindList) -> Tuple[str, constants.StatusCode]:
723    """Get next resource from the list of resources.
724
725    The list of resources should be obtained from a previous call to find_resources().
726
727    Corresponds to viFindNext function of the VISA library.
728
729    Parameters
730    ----------
731    library : ctypes.WinDLL or ctypes.CDLL
732        ctypes wrapped library.
733    find_list :
734        Describes a find list. This parameter must be created by find_resources().
735
736    Returns
737    -------
738    str
739        String identifying the location of a device
740    constants.StatusCode
741        Return value of the library call.
742
743    """
744    instrument_description = create_string_buffer(constants.VI_FIND_BUFLEN)
745    ret = library.viFindNext(find_list, instrument_description)
746    return buffer_to_text(instrument_description), ret
747
748
749def _find_resources(library, session: typing.VISARMSession, query: str):
750    """Queries VISA to locate the resources associated with a specified interface.
751
752    Corresponds to viFindRsrc function of the VISA library.
753
754    Parameters
755    ----------
756    library : ctypes.WinDLL or ctypes.CDLL
757        ctypes wrapped library.
758    session : typing.VISARMSession
759        Unique logical identifier to the ResourceManger session
760        (unused, just to uniform signatures).
761    query : str
762        A regular expression followed by an optional logical expression.
763        Use '?*' for all.
764
765    Returns
766    -------
767    ViFindList
768        Opaque object to pass to `_find_next` to access the other devices
769        resource name.
770    int
771        Number of identified devices.
772    str
773        Resource name of the first identified device
774    constants.StatusCode
775        Return value of the library call.
776
777    """
778    find_list = ViFindList()
779    return_counter = ViUInt32()
780    instrument_description = create_string_buffer(constants.VI_FIND_BUFLEN)
781
782    ret = library.viFindRsrc(
783        session, query, byref(find_list), byref(return_counter), instrument_description
784    )
785    return find_list, return_counter.value, buffer_to_text(instrument_description), ret
786
787
788def flush(library, session, mask):
789    """Retrieves the state of an attribute.
790
791    Corresponds to viGetAttribute function of the VISA library.
792
793    Parameters
794    ----------
795    library : ctypes.WinDLL or ctypes.CDLL
796        ctypes wrapped library.
797    session : Union[VISASession, VISAEventContext]
798        Unique logical identifier to a session, event, or find list.
799    attribute : Union[constants.ResourceAttribute, constants.EventAttribute]
800        Resource or event attribute for which the state query is made.
801
802    Returns
803    -------
804    Any
805        State of the queried attribute for a specified resource
806    constants.StatusCode
807        Return value of the library call.
808
809    """
810    return library.viFlush(session, mask)
811
812
813def get_attribute(library, session, attribute):
814    """Retrieves the state of an attribute.
815
816    Corresponds to viGetAttribute function of the VISA library.
817
818    Parameters
819    ----------
820    library : ctypes.WinDLL or ctypes.CDLL
821        ctypes wrapped library.
822    session : Union[VISASession, VISAEventContext]
823        Unique logical identifier to a session, event, or find list.
824    attribute : Union[constants.ResourceAttribute, constants.EventAttribute]
825        Resource or event attribute for which the state query is made.
826
827    Returns
828    -------
829    Any
830        State of the queried attribute for a specified resource
831    constants.StatusCode
832        Return value of the library call.
833
834    """
835    attr = attributes.AttributesByID[attribute]
836    datatype = getattr(types, attr.visa_type)
837    if datatype == ViString:
838        attribute_state = create_string_buffer(256)
839        ret = library.viGetAttribute(session, attribute, attribute_state)
840        return buffer_to_text(attribute_state), ret
841    # There are only 2 buffer attribute, the one we do not handle if the one
842    # to async read that is handled at a higher since we pass the buffer ourself
843    elif datatype == ViBuf:
844        if attr.visa_name == "VI_ATTR_USB_RECV_INTR_DATA":
845            length = get_attribute(
846                library, session, constants.VI_ATTR_USB_RECV_INTR_SIZE
847            )
848            attribute_state = (ViUInt8 * length)()
849            ret = library.viGetAttribute(session, attribute, byref(attribute_state))
850            return list(attribute_state), ret
851        else:
852            raise AttributeError("%s cannot be accessed directly" % attr.visa_name)
853    else:
854        attribute_state = datatype()
855        ret = library.viGetAttribute(session, attribute, byref(attribute_state))
856        return attribute_state.value, ret
857
858
859def gpib_command(library, session, data):
860    """Write GPIB command bytes on the bus.
861
862    Corresponds to viGpibCommand function of the VISA library.
863
864    Parameters
865    ----------
866    library : ctypes.WinDLL or ctypes.CDLL
867        ctypes wrapped library.
868    session : VISASession
869        Unique logical identifier to a session.
870    data : bytes
871        Data to write.
872
873    Returns
874    -------
875    int
876        Number of written bytes
877    constants.StatusCode
878        Return value of the library call.
879
880    """
881    return_count = ViUInt32()
882
883    # [ViSession, ViBuf, ViUInt32, ViPUInt32]
884    ret = library.viGpibCommand(session, data, len(data), byref(return_count))
885    return return_count.value, ret
886
887
888def gpib_control_atn(library, session, mode):
889    """Specifies the state of the ATN line and the local active controller state.
890
891    Corresponds to viGpibControlATN function of the VISA library.
892
893    Parameters
894    ----------
895    library : ctypes.WinDLL or ctypes.CDLL
896        ctypes wrapped library.
897    session : VISASession
898        Unique logical identifier to a session.
899    mode : constants.ATNLineOperation
900        State of the ATN line and optionally the local active controller state.
901
902    Returns
903    -------
904    constants.StatusCode
905        Return value of the library call.
906
907    """
908    return library.viGpibControlATN(session, mode)
909
910
911def gpib_control_ren(library, session, mode):
912    """Controls the state of the GPIB Remote Enable (REN) interface line.
913
914    Optionally the remote/local state of the device can also be set.
915
916    Corresponds to viGpibControlREN function of the VISA library.
917
918    Parameters
919    ----------
920    library : ctypes.WinDLL or ctypes.CDLL
921        ctypes wrapped library.
922    session : VISASession
923        Unique logical identifier to a session.
924    mode : constants.RENLineOperation
925        State of the REN line and optionally the device remote/local state.
926
927    Returns
928    -------
929    constants.StatusCode
930        Return value of the library call.
931
932    """
933    return library.viGpibControlREN(session, mode)
934
935
936def gpib_pass_control(library, session, primary_address, secondary_address):
937    """Tell a GPIB device to become controller in charge (CIC).
938
939    Corresponds to viGpibPassControl function of the VISA library.
940
941    Parameters
942    ----------
943    library : ctypes.WinDLL or ctypes.CDLL
944        ctypes wrapped library.
945    session : VISASession
946        Unique logical identifier to a session.
947    primary_address : int
948        Primary address of the GPIB device to which you want to pass control.
949    secondary_address : int
950        Secondary address of the targeted GPIB device.
951        If the targeted device does not have a secondary address, this parameter
952        should contain the value Constants.VI_NO_SEC_ADDR.
953
954    Returns
955    -------
956    constants.StatusCode
957        Return value of the library call.
958
959    """
960    return library.viGpibPassControl(session, primary_address, secondary_address)
961
962
963def gpib_send_ifc(library, session):
964    """Pulse the interface clear line (IFC) for at least 100 microseconds.
965
966    Corresponds to viGpibSendIFC function of the VISA library.
967
968    Parameters
969    ----------
970    library : ctypes.WinDLL or ctypes.CDLL
971        ctypes wrapped library.
972    session : VISASession
973        Unique logical identifier to a session.
974
975    Returns
976    -------
977    constants.StatusCode
978        Return value of the library call.
979
980    """
981    return library.viGpibSendIFC(session)
982
983
984def in_8(library, session, space, offset, extended=False):
985    """Reads in an 8-bit value from the specified memory space and offset.
986
987    Corresponds to viIn8* function of the VISA library.
988
989    Parameters
990    ----------
991    library : ctypes.WinDLL or ctypes.CDLL
992        ctypes wrapped library.
993    session : VISASession
994        Unique logical identifier to a session.
995    space : constants.AddressSpace
996        Specifies the address space.
997    offset : int
998        Offset (in bytes) of the address or register from which to read.
999    extended : bool, optional
1000        Use 64 bits offset independent of the platform, False by default.
1001
1002    Returns
1003    -------
1004    int
1005        Data read from memory
1006    constants.StatusCode
1007        Return value of the library call.
1008
1009    """
1010    value_8 = ViUInt8()
1011    if extended:
1012        ret = library.viIn8Ex(session, space, offset, byref(value_8))
1013    else:
1014        ret = library.viIn8(session, space, offset, byref(value_8))
1015    return value_8.value, ret
1016
1017
1018def in_16(library, session, space, offset, extended=False):
1019    """Reads in an 16-bit value from the specified memory space and offset.
1020
1021    Corresponds to viIn16* function of the VISA library.
1022
1023    Parameters
1024    ----------
1025    library : ctypes.WinDLL or ctypes.CDLL
1026        ctypes wrapped library.
1027    session : VISASession
1028        Unique logical identifier to a session.
1029    space : constants.AddressSpace
1030        Specifies the address space.
1031    offset : int
1032        Offset (in bytes) of the address or register from which to read.
1033    extended : bool, optional
1034        Use 64 bits offset independent of the platform, False by default.
1035
1036    Returns
1037    -------
1038    int
1039        Data read from memory
1040    constants.StatusCode
1041        Return value of the library call.
1042
1043    """
1044    value_16 = ViUInt16()
1045    if extended:
1046        ret = library.viIn16Ex(session, space, offset, byref(value_16))
1047    else:
1048        ret = library.viIn16(session, space, offset, byref(value_16))
1049    return value_16.value, ret
1050
1051
1052def in_32(library, session, space, offset, extended=False):
1053    """Reads in an 32-bit value from the specified memory space and offset.
1054
1055    Corresponds to viIn32* function of the VISA library.
1056
1057    Parameters
1058    ----------
1059    library : ctypes.WinDLL or ctypes.CDLL
1060        ctypes wrapped library.
1061    session : VISASession
1062        Unique logical identifier to a session.
1063    space : constants.AddressSpace
1064        Specifies the address space.
1065    offset : int
1066        Offset (in bytes) of the address or register from which to read.
1067    extended : bool, optional
1068        Use 64 bits offset independent of the platform, False by default.
1069
1070    Returns
1071    -------
1072    int
1073        Data read from memory
1074    constants.StatusCode
1075        Return value of the library call.
1076
1077    """
1078    value_32 = ViUInt32()
1079    if extended:
1080        ret = library.viIn32Ex(session, space, offset, byref(value_32))
1081    else:
1082        ret = library.viIn32(session, space, offset, byref(value_32))
1083    return value_32.value, ret
1084
1085
1086def in_64(library, session, space, offset, extended=False):
1087    """Reads in an 64-bit value from the specified memory space and offset.
1088
1089    Corresponds to viIn64* function of the VISA library.
1090
1091    Parameters
1092    ----------
1093    library : ctypes.WinDLL or ctypes.CDLL
1094        ctypes wrapped library.
1095    session : VISASession
1096        Unique logical identifier to a session.
1097    space : constants.AddressSpace
1098        Specifies the address space.
1099    offset : int
1100        Offset (in bytes) of the address or register from which to read.
1101    extended : bool, optional
1102        Use 64 bits offset independent of the platform, False by default.
1103
1104    Returns
1105    -------
1106    int
1107        Data read from memory
1108    constants.StatusCode
1109        Return value of the library call.
1110
1111    """
1112    value_64 = ViUInt64()
1113    if extended:
1114        ret = library.viIn64Ex(session, space, offset, byref(value_64))
1115    else:
1116        ret = library.viIn64(session, space, offset, byref(value_64))
1117    return value_64.value, ret
1118
1119
1120def install_handler(
1121    library, session, event_type, handler, user_handle: Any
1122) -> Tuple[typing.VISAHandler, Any, Any, constants.StatusCode]:
1123    """Install handlers for event callbacks.
1124
1125    Corresponds to viInstallHandler function of the VISA library.
1126
1127    Parameters
1128    ----------
1129    library : ctypes.WinDLL or ctypes.CDLL
1130        ctypes wrapped library.
1131    session : VISASession
1132        Unique logical identifier to a session.
1133    event_type : constants.EventType
1134        Logical event identifier.
1135    handler : VISAHandler
1136        Reference to a handler to be installed by a client application.
1137    user_handle : Any
1138        Value specified by an application that can be used for identifying
1139        handlers uniquely for an event type.
1140
1141    Returns
1142    -------
1143    handler : VISAHandler
1144        Handler to be installed by a client application.
1145    converted_user_handle :
1146        Converted user handle to match the underlying library. This version
1147        of the handle should be used in further call to the library.
1148    converted_handler :
1149        Converted version of the handler satisfying to backend library.
1150    status_code : constants.StatusCode
1151        Return value of the library call
1152
1153    """
1154    # Should be Optional[_CData] but that type cannot be imported
1155    converted_user_handle: object = None
1156    if user_handle is not None:
1157        if isinstance(user_handle, int):
1158            converted_user_handle = c_long(user_handle)
1159        elif isinstance(user_handle, float):
1160            converted_user_handle = c_double(user_handle)
1161        elif isinstance(user_handle, str):
1162            converted_user_handle = c_wchar_p(user_handle)
1163        elif isinstance(user_handle, list):
1164            for element in user_handle:
1165                if not isinstance(element, int):
1166                    # Mypy cannot track the fact that the list has to contain float
1167                    converted_user_handle = (c_double * len(user_handle))(  # type: ignore
1168                        *tuple(user_handle)
1169                    )
1170                    break
1171            else:
1172                converted_user_handle = (c_long * len(user_handle))(*tuple(user_handle))
1173        else:
1174            try:
1175                # check if it is already a ctypes
1176                byref(user_handle)
1177                converted_user_handle = user_handle
1178            except TypeError:
1179                raise TypeError(
1180                    "Type not allowed as user handle: %s" % type(user_handle)
1181                )
1182
1183    with set_user_handle_type(library, converted_user_handle):
1184
1185        if ctwrapper.WRAP_HANDLER:
1186            # Wrap the handler to provide a non-wrapper specific interface
1187            def handler_wrapper(
1188                ctype_session, ctype_event_type, ctype_event_context, ctype_user_handle
1189            ):
1190                handler(
1191                    ctype_session.value,
1192                    ctype_event_type,
1193                    ctype_event_context.value,
1194                    ctype_user_handle.contents
1195                    if ctype_user_handle
1196                    else ctype_user_handle,
1197                )
1198                return 0
1199
1200            update_wrapper(handler_wrapper, handler)
1201        else:
1202            handler_wrapper = handler
1203
1204        converted_handler = ViHndlr(handler_wrapper)
1205        if user_handle is None:
1206            ret = library.viInstallHandler(session, event_type, converted_handler, None)
1207        else:
1208            ret = library.viInstallHandler(
1209                session,
1210                event_type,
1211                converted_handler,
1212                byref(converted_user_handle),  # type: ignore
1213            )
1214
1215    return handler, converted_user_handle, converted_handler, ret
1216
1217
1218def lock(library, session, lock_type, timeout, requested_key=None):
1219    """Establishes an access mode to the specified resources.
1220
1221    Corresponds to viLock function of the VISA library.
1222
1223    Parameters
1224    ----------
1225    library : ctypes.WinDLL or ctypes.CDLL
1226        ctypes wrapped library.
1227    session : VISASession
1228        Unique logical identifier to a session.
1229    lock_type : constants.Lock
1230        Specifies the type of lock requested.
1231    timeout : int
1232        Absolute time period (in milliseconds) that a resource waits to get
1233        unlocked by the locking session before returning an error.
1234    requested_key : Optional[str], optional
1235        Requested locking key in the case of a shared lock. For an exclusive
1236        lock it should be None.
1237
1238    Returns
1239    -------
1240    Optional[str]
1241        Key that can then be passed to other sessions to share the lock, or
1242        None for an exclusive lock.
1243    constants.StatusCode
1244        Return value of the library call.
1245
1246    """
1247    if lock_type == constants.AccessModes.exclusive_lock:
1248        requested_key = None
1249        access_key = None
1250    else:
1251        access_key = create_string_buffer(256)
1252    ret = library.viLock(session, lock_type, timeout, requested_key, access_key)
1253    if access_key is None:
1254        return None, ret
1255    else:
1256        return access_key.value, ret
1257
1258
1259def map_address(
1260    library, session, map_space, map_base, map_size, access=False, suggested=None
1261):
1262    """Maps the specified memory space into the process's address space.
1263
1264    Corresponds to viMapAddress function of the VISA library.
1265
1266    Parameters
1267    ----------
1268    library : ctypes.WinDLL or ctypes.CDLL
1269        ctypes wrapped library.
1270    session : VISASession
1271        Unique logical identifier to a session.
1272    map_space : constants.AddressSpace
1273        Specifies the address space to map.
1274    map_base : int
1275        Offset (in bytes) of the memory to be mapped.
1276    map_size : int
1277        Amount of memory to map (in bytes).
1278    access : False
1279        Unused parameter.
1280    suggested : Optional[int], optional
1281        If not None, the operating system attempts to map the memory to the
1282        address specified. There is no guarantee, however, that the memory
1283        will be mapped to that address. This operation may map the memory
1284        into an address region different from the suggested one.
1285
1286    Returns
1287    -------
1288    int
1289        Address in your process space where the memory was mapped
1290    constants.StatusCode
1291        Return value of the library call.
1292
1293    """
1294    if access is False:
1295        access = constants.VI_FALSE
1296    elif access != constants.VI_FALSE:
1297        warnings.warn("In enable_event, context will be set VI_NULL.")
1298        access = constants.VI_FALSE
1299    address = ViAddr()
1300    ret = library.viMapAddress(
1301        session, map_space, map_base, map_size, access, suggested, byref(address)
1302    )
1303    return address, ret
1304
1305
1306def map_trigger(library, session, trigger_source, trigger_destination, mode):
1307    """Map the specified trigger source line to the specified destination line.
1308
1309    Corresponds to viMapTrigger function of the VISA library.
1310
1311    Parameters
1312    ----------
1313    library : ctypes.WinDLL or ctypes.CDLL
1314        ctypes wrapped library.
1315    session : VISASession
1316        Unique logical identifier to a session.
1317    trigger_source : constants.InputTriggerLine
1318        Source line from which to map.
1319    trigger_destination : constants.OutputTriggerLine
1320        Destination line to which to map.
1321    mode : None, optional
1322        Always None for this version of the VISA specification.
1323
1324    Returns
1325    -------
1326    constants.StatusCode
1327        Return value of the library call.
1328
1329    """
1330    return library.viMapTrigger(session, trigger_source, trigger_destination, mode)
1331
1332
1333def memory_allocation(library, session, size, extended=False):
1334    """Allocate memory from a resource's memory region.
1335
1336    Corresponds to viMemAlloc* functions of the VISA library.
1337
1338    Parameters
1339    ----------
1340    library : ctypes.WinDLL or ctypes.CDLL
1341        ctypes wrapped library.
1342    session : VISASession
1343        Unique logical identifier to a session.
1344    size : int
1345        Specifies the size of the allocation.
1346    extended : bool, optional
1347        Use 64 bits offset independent of the platform.
1348
1349    Returns
1350    -------
1351    int
1352        offset of the allocated memory
1353    constants.StatusCode
1354        Return value of the library call.
1355
1356    """
1357    offset = ViBusAddress()
1358    if extended:
1359        ret = library.viMemAllocEx(session, size, byref(offset))
1360    else:
1361        ret = library.viMemAlloc(session, size, byref(offset))
1362    return offset, ret
1363
1364
1365def memory_free(library, session, offset, extended=False):
1366    """Frees memory previously allocated using the memory_allocation() operation.
1367
1368    Corresponds to viMemFree* function of the VISA library.
1369
1370    Parameters
1371    ----------
1372    library : ctypes.WinDLL or ctypes.CDLL
1373        ctypes wrapped library.
1374    session : VISASession
1375        Unique logical identifier to a session.
1376    offset : int
1377        Offset of the memory to free.
1378    extended : bool, optional
1379        Use 64 bits offset independent of the platform.
1380
1381    Returns
1382    -------
1383    constants.StatusCode
1384        Return value of the library call.
1385
1386    """
1387    if extended:
1388        return library.viMemFreeEx(session, offset)
1389    else:
1390        return library.viMemFree(session, offset)
1391
1392
1393def move(
1394    library,
1395    session,
1396    source_space,
1397    source_offset,
1398    source_width,
1399    destination_space,
1400    destination_offset,
1401    destination_width,
1402    length,
1403):
1404    """Moves a block of data.
1405
1406    Corresponds to viMove function of the VISA library.
1407
1408    Parameters
1409    ----------
1410    library : ctypes.WinDLL or ctypes.CDLL
1411        ctypes wrapped library.
1412    session : VISASession
1413        Unique logical identifier to a session.
1414    source_space : constants.AddressSpace
1415        Specifies the address space of the source.
1416    source_offset : int
1417        Offset of the starting address or register from which to read.
1418    source_width : constants.DataWidth
1419        Specifies the data width of the source.
1420    destination_space : constants.AddressSpace
1421        Specifies the address space of the destination.
1422    destination_offset : int
1423        Offset of the starting address or register to which to write.
1424    destination_width : constants.DataWidth
1425        Specifies the data width of the destination.
1426    length: int
1427        Number of elements to transfer, where the data width of the
1428        elements to transfer is identical to the source data width.
1429
1430    Returns
1431    -------
1432    constants.StatusCode
1433        Return value of the library call.
1434
1435    """
1436    return library.viMove(
1437        session,
1438        source_space,
1439        source_offset,
1440        source_width,
1441        destination_space,
1442        destination_offset,
1443        destination_width,
1444        length,
1445    )
1446
1447
1448def move_asynchronously(
1449    library,
1450    session,
1451    source_space,
1452    source_offset,
1453    source_width,
1454    destination_space,
1455    destination_offset,
1456    destination_width,
1457    length,
1458):
1459    """Moves a block of data asynchronously.
1460
1461    Corresponds to viMoveAsync function of the VISA library.
1462
1463    Parameters
1464    ----------
1465    library : ctypes.WinDLL or ctypes.CDLL
1466        ctypes wrapped library.
1467    session : VISASession
1468        Unique logical identifier to a session.
1469    source_space : constants.AddressSpace
1470        Specifies the address space of the source.
1471    source_offset : int
1472        Offset of the starting address or register from which to read.
1473    source_width : constants.DataWidth
1474        Specifies the data width of the source.
1475    destination_space : constants.AddressSpace
1476        Specifies the address space of the destination.
1477    destination_offset : int
1478        Offset of the starting address or register to which to write.
1479    destination_width : constants.DataWidth
1480        Specifies the data width of the destination.
1481    length : int
1482        Number of elements to transfer, where the data width of the
1483        elements to transfer is identical to the source data width.
1484
1485    Returns
1486    -------
1487    VISAJobID
1488        Job identifier of this asynchronous move operation
1489    constants.StatusCode
1490        Return value of the library call.
1491
1492    """
1493    job_id = ViJobId()
1494    ret = library.viMoveAsync(
1495        session,
1496        source_space,
1497        source_offset,
1498        source_width,
1499        destination_space,
1500        destination_offset,
1501        destination_width,
1502        length,
1503        byref(job_id),
1504    )
1505    return job_id, ret
1506
1507
1508def move_in_8(library, session, space, offset, length, extended=False):
1509    """Moves an 8-bit block of data to local memory.
1510
1511    Corresponds to viMoveIn8* functions of the VISA library.
1512
1513    Parameters
1514    ----------
1515    library : ctypes.WinDLL or ctypes.CDLL
1516        ctypes wrapped library.
1517    session : VISASession
1518        Unique logical identifier to a session.
1519    space : constants.AddressSpace
1520        Address space from which to move the data.
1521    offset : int
1522        Offset (in bytes) of the address or register from which to read.
1523    length : int
1524            Number of elements to transfer, where the data width of
1525            the elements to transfer is identical to the source data width.
1526    extended : bool, optional
1527        Use 64 bits offset independent of the platform, by default False.
1528
1529    Returns
1530    -------
1531    data : List[int]
1532        Data read from the bus
1533    status_code : constants.StatusCode
1534        Return value of the library call.
1535
1536    """
1537    buffer_8 = (ViUInt8 * length)()
1538    if extended:
1539        ret = library.viMoveIn8Ex(session, space, offset, length, buffer_8)
1540    else:
1541        ret = library.viMoveIn8(session, space, offset, length, buffer_8)
1542    return list(buffer_8), ret
1543
1544
1545def move_in_16(library, session, space, offset, length, extended=False):
1546    """Moves an 16-bit block of data to local memory.
1547
1548    Corresponds to viMoveIn816 functions of the VISA library.
1549
1550    Parameters
1551    ----------
1552    library : ctypes.WinDLL or ctypes.CDLL
1553        ctypes wrapped library.
1554    session : VISASession
1555        Unique logical identifier to a session.
1556    space : constants.AddressSpace
1557        Address space from which to move the data.
1558    offset : int
1559        Offset (in bytes) of the address or register from which to read.
1560    length : int
1561            Number of elements to transfer, where the data width of
1562            the elements to transfer is identical to the source data width.
1563    extended : bool, optional
1564        Use 64 bits offset independent of the platform, by default False.
1565
1566    Returns
1567    -------
1568    data : List[int]
1569        Data read from the bus
1570    status_code : constants.StatusCode
1571        Return value of the library call.
1572
1573    """
1574    buffer_16 = (ViUInt16 * length)()
1575    if extended:
1576        ret = library.viMoveIn16Ex(session, space, offset, length, buffer_16)
1577    else:
1578        ret = library.viMoveIn16(session, space, offset, length, buffer_16)
1579
1580    return list(buffer_16), ret
1581
1582
1583def move_in_32(library, session, space, offset, length, extended=False):
1584    """Moves an 32-bit block of data to local memory.
1585
1586    Corresponds to viMoveIn32* functions of the VISA library.
1587
1588    Parameters
1589    ----------
1590    library : ctypes.WinDLL or ctypes.CDLL
1591        ctypes wrapped library.
1592    session : VISASession
1593        Unique logical identifier to a session.
1594    space : constants.AddressSpace
1595        Address space from which to move the data.
1596    offset : int
1597        Offset (in bytes) of the address or register from which to read.
1598    length : int
1599            Number of elements to transfer, where the data width of
1600            the elements to transfer is identical to the source data width.
1601    extended : bool, optional
1602        Use 64 bits offset independent of the platform, by default False.
1603
1604    Returns
1605    -------
1606    data : List[int]
1607        Data read from the bus
1608    status_code : constants.StatusCode
1609        Return value of the library call.
1610
1611    """
1612    buffer_32 = (ViUInt32 * length)()
1613    if extended:
1614        ret = library.viMoveIn32Ex(session, space, offset, length, buffer_32)
1615    else:
1616        ret = library.viMoveIn32(session, space, offset, length, buffer_32)
1617
1618    return list(buffer_32), ret
1619
1620
1621def move_in_64(library, session, space, offset, length, extended=False):
1622    """Moves an 64-bit block of data to local memory.
1623
1624    Corresponds to viMoveIn8* functions of the VISA library.
1625
1626    Parameters
1627    ----------
1628    library : ctypes.WinDLL or ctypes.CDLL
1629        ctypes wrapped library.
1630    session : VISASession
1631        Unique logical identifier to a session.
1632    space : constants.AddressSpace
1633        Address space from which to move the data.
1634    offset : int
1635        Offset (in bytes) of the address or register from which to read.
1636    length : int
1637            Number of elements to transfer, where the data width of
1638            the elements to transfer is identical to the source data width.
1639    extended : bool, optional
1640        Use 64 bits offset independent of the platform, by default False.
1641
1642    Returns
1643    -------
1644    data : List[int]
1645        Data read from the bus
1646    status_code : constants.StatusCode
1647        Return value of the library call.
1648
1649    """
1650    buffer_64 = (ViUInt64 * length)()
1651    if extended:
1652        ret = library.viMoveIn64Ex(session, space, offset, length, buffer_64)
1653    else:
1654        ret = library.viMoveIn64(session, space, offset, length, buffer_64)
1655
1656    return list(buffer_64), ret
1657
1658
1659def move_out_8(library, session, space, offset, length, data, extended=False):
1660    """Moves an 8-bit block of data from local memory.
1661
1662    Corresponds to viMoveOut8* functions of the VISA library.
1663
1664    Parameters
1665    ----------
1666    library : ctypes.WinDLL or ctypes.CDLL
1667        ctypes wrapped library.
1668    session : VISASession
1669        Unique logical identifier to a session.
1670    space : constants.AddressSpace
1671        Address space into which move the data.
1672    offset : int
1673        Offset (in bytes) of the address or register from which to read.
1674    length : int
1675        Number of elements to transfer, where the data width of
1676        the elements to transfer is identical to the source data width.
1677    data : Iterable[int]
1678        Data to write to bus.
1679    extended : bool, optional
1680        Use 64 bits offset independent of the platform, by default False.
1681
1682    Returns
1683    -------
1684    constants.StatusCode
1685        Return value of the library call.
1686
1687    """
1688    converted_buffer = (ViUInt8 * length)(*tuple(data))
1689    if extended:
1690        return library.viMoveOut8Ex(session, space, offset, length, converted_buffer)
1691    else:
1692        return library.viMoveOut8(session, space, offset, length, converted_buffer)
1693
1694
1695def move_out_16(library, session, space, offset, length, data, extended=False):
1696    """Moves an 16-bit block of data from local memory.
1697
1698    Corresponds to viMoveOut16* functions of the VISA library.
1699
1700    Parameters
1701    ----------
1702    library : ctypes.WinDLL or ctypes.CDLL
1703        ctypes wrapped library.
1704    session : VISASession
1705        Unique logical identifier to a session.
1706    space : constants.AddressSpace
1707        Address space into which move the data.
1708    offset : int
1709        Offset (in bytes) of the address or register from which to read.
1710    length : int
1711        Number of elements to transfer, where the data width of
1712        the elements to transfer is identical to the source data width.
1713    data : Iterable[int]
1714        Data to write to bus.
1715    extended : bool, optional
1716        Use 64 bits offset independent of the platform, by default False.
1717
1718    Returns
1719    -------
1720    constants.StatusCode
1721        Return value of the library call.
1722
1723    """
1724    converted_buffer = (ViUInt16 * length)(*tuple(data))
1725    if extended:
1726        return library.viMoveOut16Ex(session, space, offset, length, converted_buffer)
1727    else:
1728        return library.viMoveOut16(session, space, offset, length, converted_buffer)
1729
1730
1731def move_out_32(library, session, space, offset, length, data, extended=False):
1732    """Moves an 32-bit block of data from local memory.
1733
1734    Corresponds to viMoveOut32* functions of the VISA library.
1735
1736    Parameters
1737    ----------
1738    library : ctypes.WinDLL or ctypes.CDLL
1739        ctypes wrapped library.
1740    session : VISASession
1741        Unique logical identifier to a session.
1742    space : constants.AddressSpace
1743        Address space into which move the data.
1744    offset : int
1745        Offset (in bytes) of the address or register from which to read.
1746    length : int
1747        Number of elements to transfer, where the data width of
1748        the elements to transfer is identical to the source data width.
1749    data : Iterable[int]
1750        Data to write to bus.
1751    extended : bool, optional
1752        Use 64 bits offset independent of the platform, by default False.
1753
1754    Returns
1755    -------
1756    constants.StatusCode
1757        Return value of the library call.
1758
1759
1760    """
1761    converted_buffer = (ViUInt32 * length)(*tuple(data))
1762    if extended:
1763        return library.viMoveOut32Ex(session, space, offset, length, converted_buffer)
1764    else:
1765        return library.viMoveOut32(session, space, offset, length, converted_buffer)
1766
1767
1768def move_out_64(library, session, space, offset, length, data, extended=False):
1769    """Moves an 64-bit block of data from local memory.
1770
1771    Corresponds to viMoveOut64* functions of the VISA library.
1772
1773    Parameters
1774    ----------
1775    library : ctypes.WinDLL or ctypes.CDLL
1776        ctypes wrapped library.
1777    session : VISASession
1778        Unique logical identifier to a session.
1779    space : constants.AddressSpace
1780        Address space into which move the data.
1781    offset : int
1782        Offset (in bytes) of the address or register from which to read.
1783    length : int
1784        Number of elements to transfer, where the data width of
1785        the elements to transfer is identical to the source data width.
1786    data : Iterable[int]
1787        Data to write to bus.
1788    extended : bool, optional
1789        Use 64 bits offset independent of the platform, by default False.
1790
1791    Returns
1792    -------
1793    constants.StatusCode
1794        Return value of the library call.
1795
1796    """
1797    converted_buffer = (ViUInt64 * length)(*tuple(data))
1798    if extended:
1799        return library.viMoveOut64Ex(session, space, offset, length, converted_buffer)
1800    else:
1801        return library.viMoveOut64(session, space, offset, length, converted_buffer)
1802
1803
1804# noinspection PyShadowingBuiltins
1805def open(
1806    library,
1807    session,
1808    resource_name,
1809    access_mode=constants.AccessModes.no_lock,
1810    open_timeout=constants.VI_TMO_IMMEDIATE,
1811):
1812    """Opens a session to the specified resource.
1813
1814    Corresponds to viOpen function of the VISA library.
1815
1816    Parameters
1817    ----------
1818    library : ctypes.WinDLL or ctypes.CDLL
1819        ctypes wrapped library.
1820    session : VISARMSession
1821        Resource Manager session (should always be a session returned from
1822        open_default_resource_manager()).
1823    resource_name : str
1824        Unique symbolic name of a resource.
1825    access_mode : constants.AccessModes, optional
1826        Specifies the mode by which the resource is to be accessed.
1827    open_timeout : int
1828        If the ``access_mode`` parameter requests a lock, then this
1829        parameter specifies the absolute time period (in milliseconds) that
1830        the resource waits to get unlocked before this operation returns an
1831        error.
1832
1833    Returns
1834    -------
1835    VISASession
1836        Unique logical identifier reference to a session
1837    constants.StatusCode
1838        Return value of the library call.
1839
1840    """
1841    try:
1842        open_timeout = int(open_timeout)
1843    except ValueError:
1844        raise ValueError(
1845            "open_timeout (%r) must be an integer (or compatible type)" % open_timeout
1846        )
1847    out_session = ViSession()
1848
1849    # [ViSession, ViRsrc, ViAccessMode, ViUInt32, ViPSession]
1850    # ViRsrc converts from (str, unicode, bytes) to bytes
1851    ret = library.viOpen(
1852        session, resource_name, access_mode, open_timeout, byref(out_session)
1853    )
1854    return out_session.value, ret
1855
1856
1857def open_default_resource_manager(library):
1858    """This function returns a session to the Default Resource Manager resource.
1859
1860    Corresponds to viOpenDefaultRM function of the VISA library.
1861
1862    Returns
1863    -------
1864    VISARMSession
1865        Unique logical identifier to a Default Resource Manager session
1866    constants.StatusCode
1867        Return value of the library call.
1868
1869    """
1870    session = ViSession()
1871    ret = library.viOpenDefaultRM(byref(session))
1872    return session.value, ret
1873
1874
1875def out_8(library, session, space, offset, data, extended=False):
1876    """Write an 8-bit value to the specified memory space and offset.
1877
1878    Corresponds to viOut8* functions of the VISA library.
1879
1880    Parameters
1881    ----------
1882    library : ctypes.WinDLL or ctypes.CDLL
1883        ctypes wrapped library.
1884    session : VISASession
1885        Unique logical identifier to a session.
1886    space : constants.AddressSpace
1887        Address space into which to write.
1888    offset : int
1889        Offset (in bytes) of the address or register from which to read.
1890    data : int
1891        Data to write to bus.
1892    extended : bool, optional
1893        Use 64 bits offset independent of the platform.
1894
1895    Returns
1896    -------
1897    constants.StatusCode
1898        Return value of the library call.
1899
1900    """
1901    if extended:
1902        return library.viOut8Ex(session, space, offset, data)
1903    else:
1904        return library.viOut8(session, space, offset, data)
1905
1906
1907def out_16(library, session, space, offset, data, extended=False):
1908    """Write a 16-bit value to the specified memory space and offset.
1909
1910    Corresponds to viOut16* functions of the VISA library.
1911
1912    Parameters
1913    ----------
1914    library : ctypes.WinDLL or ctypes.CDLL
1915        ctypes wrapped library.
1916    session : VISASession
1917        Unique logical identifier to a session.
1918    space : constants.AddressSpace
1919        Address space into which to write.
1920    offset : int
1921        Offset (in bytes) of the address or register from which to read.
1922    data : int
1923        Data to write to bus.
1924    extended : bool, optional
1925        Use 64 bits offset independent of the platform.
1926
1927    Returns
1928    -------
1929    constants.StatusCode
1930        Return value of the library call.
1931
1932    """
1933    if extended:
1934        return library.viOut16Ex(session, space, offset, data, extended=False)
1935    else:
1936        return library.viOut16(session, space, offset, data, extended=False)
1937
1938
1939def out_32(library, session, space, offset, data, extended=False):
1940    """Write a 32-bit value to the specified memory space and offset.
1941
1942    Corresponds to viOut32* functions of the VISA library.
1943
1944    Parameters
1945    ----------
1946    library : ctypes.WinDLL or ctypes.CDLL
1947        ctypes wrapped library.
1948    session : VISASession
1949        Unique logical identifier to a session.
1950    space : constants.AddressSpace
1951        Address space into which to write.
1952    offset : int
1953        Offset (in bytes) of the address or register from which to read.
1954    data : int
1955        Data to write to bus.
1956    extended : bool, optional
1957        Use 64 bits offset independent of the platform.
1958
1959    Returns
1960    -------
1961    constants.StatusCode
1962        Return value of the library call.
1963
1964    """
1965    if extended:
1966        return library.viOut32Ex(session, space, offset, data)
1967    else:
1968        return library.viOut32(session, space, offset, data)
1969
1970
1971def out_64(library, session, space, offset, data, extended=False):
1972    """Write a 64-bit value to the specified memory space and offset.
1973
1974    Corresponds to viOut64* functions of the VISA library.
1975
1976    Parameters
1977    ----------
1978    library : ctypes.WinDLL or ctypes.CDLL
1979        ctypes wrapped library.
1980    session : VISASession
1981        Unique logical identifier to a session.
1982    space : constants.AddressSpace
1983        Address space into which to write.
1984    offset : int
1985        Offset (in bytes) of the address or register from which to read.
1986    data : int
1987        Data to write to bus.
1988    extended : bool, optional
1989        Use 64 bits offset independent of the platform.
1990
1991    Returns
1992    -------
1993    constants.StatusCode
1994        Return value of the library call.
1995
1996    """
1997    if extended:
1998        return library.viOut64Ex(session, space, offset, data)
1999    else:
2000        return library.viOut64(session, space, offset, data)
2001
2002
2003def parse_resource(library, session, resource_name):
2004    """Parse a resource string to get the interface information.
2005
2006    Corresponds to viParseRsrc function of the VISA library.
2007
2008    Parameters
2009    ----------
2010    library : ctypes.WinDLL or ctypes.CDLL
2011        ctypes wrapped library.
2012    session : VISARMSession
2013        Resource Manager session (should always be the Default Resource
2014        Manager for VISA returned from open_default_resource_manager()).
2015    resource_name : str
2016            Unique symbolic name of a resource.
2017
2018    Returns
2019    -------
2020    ResourceInfo
2021        Resource information with interface type and board number
2022    constants.StatusCode
2023        Return value of the library call.
2024
2025    """
2026    interface_type = ViUInt16()
2027    interface_board_number = ViUInt16()
2028
2029    # [ViSession, ViRsrc, ViPUInt16, ViPUInt16]
2030    # ViRsrc converts from (str, unicode, bytes) to bytes
2031    ret = library.viParseRsrc(
2032        session, resource_name, byref(interface_type), byref(interface_board_number)
2033    )
2034    return (
2035        ResourceInfo(
2036            constants.InterfaceType(interface_type.value),
2037            interface_board_number.value,
2038            None,
2039            None,
2040            None,
2041        ),
2042        ret,
2043    )
2044
2045
2046def parse_resource_extended(library, session, resource_name):
2047    """Parse a resource string to get extended interface information.
2048
2049    Corresponds to viParseRsrcEx function of the VISA library.
2050
2051    Parameters
2052    ----------
2053    library : ctypes.WinDLL or ctypes.CDLL
2054        ctypes wrapped library.
2055    session : VISARMSession
2056        Resource Manager session (should always be the Default Resource
2057        Manager for VISA returned from open_default_resource_manager()).
2058    resource_name : str
2059            Unique symbolic name of a resource.
2060
2061    Returns
2062    -------
2063    ResourceInfo
2064        Resource information with interface type and board number
2065    constants.StatusCode
2066        Return value of the library call.
2067
2068    """
2069    interface_type = ViUInt16()
2070    interface_board_number = ViUInt16()
2071    resource_class = create_string_buffer(constants.VI_FIND_BUFLEN)
2072    unaliased_expanded_resource_name = create_string_buffer(constants.VI_FIND_BUFLEN)
2073    alias_if_exists = create_string_buffer(constants.VI_FIND_BUFLEN)
2074
2075    # [ViSession, ViRsrc, ViPUInt16, ViPUInt16, ViAChar, ViAChar, ViAChar]
2076    # ViRsrc converts from (str, unicode, bytes) to bytes
2077    ret = library.viParseRsrcEx(
2078        session,
2079        resource_name,
2080        byref(interface_type),
2081        byref(interface_board_number),
2082        resource_class,
2083        unaliased_expanded_resource_name,
2084        alias_if_exists,
2085    )
2086
2087    res = [
2088        buffer_to_text(val)
2089        for val in (resource_class, unaliased_expanded_resource_name, alias_if_exists)
2090    ]
2091
2092    if res[-1] == "":
2093        res[-1] = None
2094
2095    return (
2096        ResourceInfo(
2097            constants.InterfaceType(interface_type.value),
2098            interface_board_number.value,
2099            *res
2100        ),
2101        ret,
2102    )
2103
2104
2105def peek_8(library, session, address):
2106    """Read an 8-bit value from the specified address.
2107
2108    Corresponds to viPeek8 function of the VISA library.
2109
2110    Parameters
2111    ----------
2112    library : ctypes.WinDLL or ctypes.CDLL
2113        ctypes wrapped library.
2114    session : VISASession
2115        Unique logical identifier to a session.
2116    address : VISAMemoryAddress
2117        Source address to read the value.
2118
2119    Returns
2120    -------
2121    int
2122        Data read from bus
2123    constants.StatusCode
2124        Return value of the library call.
2125
2126    """
2127    value_8 = ViUInt8()
2128    ret = library.viPeek8(session, address, byref(value_8))
2129    return value_8.value, ret
2130
2131
2132def peek_16(library, session, address):
2133    """Read an 16-bit value from the specified address.
2134
2135    Corresponds to viPeek16 function of the VISA library.
2136
2137    Parameters
2138    ----------
2139    library : ctypes.WinDLL or ctypes.CDLL
2140        ctypes wrapped library.
2141    session : VISASession
2142        Unique logical identifier to a session.
2143    address : VISAMemoryAddress
2144        Source address to read the value.
2145
2146    Returns
2147    -------
2148    int
2149        Data read from bus
2150    constants.StatusCode
2151        Return value of the library call.
2152
2153    """
2154    value_16 = ViUInt16()
2155    ret = library.viPeek16(session, address, byref(value_16))
2156    return value_16.value, ret
2157
2158
2159def peek_32(library, session, address):
2160    """Read an 32-bit value from the specified address.
2161
2162    Corresponds to viPeek32 function of the VISA library.
2163
2164    Parameters
2165    ----------
2166    library : ctypes.WinDLL or ctypes.CDLL
2167        ctypes wrapped library.
2168    session : VISASession
2169        Unique logical identifier to a session.
2170    address : VISAMemoryAddress
2171        Source address to read the value.
2172
2173    Returns
2174    -------
2175    int
2176        Data read from bus
2177    constants.StatusCode
2178        Return value of the library call.
2179
2180    """
2181    value_32 = ViUInt32()
2182    ret = library.viPeek32(session, address, byref(value_32))
2183    return value_32.value, ret
2184
2185
2186def peek_64(library, session, address):
2187    """Read an 64-bit value from the specified address.
2188
2189    Corresponds to viPeek64 function of the VISA library.
2190
2191    Parameters
2192    ----------
2193    library : ctypes.WinDLL or ctypes.CDLL
2194        ctypes wrapped library.
2195    session : VISASession
2196        Unique logical identifier to a session.
2197    address : VISAMemoryAddress
2198        Source address to read the value.
2199
2200    Returns
2201    -------
2202    int
2203        Data read from bus
2204    constants.StatusCode
2205        Return value of the library call.
2206
2207    """
2208    value_64 = ViUInt64()
2209    ret = library.viPeek64(session, address, byref(value_64))
2210    return value_64.value, ret
2211
2212
2213def poke_8(library, session, address, data):
2214    """Write an 8-bit value to the specified address.
2215
2216    Corresponds to viPoke8 function of the VISA library.
2217
2218    Parameters
2219    ----------
2220    library : ctypes.WinDLL or ctypes.CDLL
2221        ctypes wrapped library.
2222    session : VISASession
2223        Unique logical identifier to a session.
2224    address : VISAMemoryAddress
2225        Source address to read the value.
2226    data : int
2227        Data to write.
2228
2229    Returns
2230    -------
2231    constants.StatusCode
2232        Return value of the library call.
2233
2234    """
2235    return library.viPoke8(session, address, data)
2236
2237
2238def poke_16(library, session, address, data):
2239    """Write an 16-bit value to the specified address.
2240
2241    Corresponds to viPoke16 function of the VISA library.
2242
2243    Parameters
2244    ----------
2245    library : ctypes.WinDLL or ctypes.CDLL
2246        ctypes wrapped library.
2247    session : VISASession
2248        Unique logical identifier to a session.
2249    address : VISAMemoryAddress
2250        Source address to read the value.
2251    data : int
2252        Data to write.
2253
2254    Returns
2255    -------
2256    constants.StatusCode
2257        Return value of the library call.
2258
2259    """
2260    return library.viPoke16(session, address, data)
2261
2262
2263def poke_32(library, session, address, data):
2264    """Write an 32-bit value to the specified address.
2265
2266    Corresponds to viPoke32 function of the VISA library.
2267
2268    Parameters
2269    ----------
2270    library : ctypes.WinDLL or ctypes.CDLL
2271        ctypes wrapped library.
2272    session : VISASession
2273        Unique logical identifier to a session.
2274    address : VISAMemoryAddress
2275        Source address to read the value.
2276    data : int
2277        Data to write.
2278
2279    Returns
2280    -------
2281    constants.StatusCode
2282        Return value of the library call.
2283
2284    """
2285    return library.viPoke32(session, address, data)
2286
2287
2288def poke_64(library, session, address, data):
2289    """Write an 64-bit value to the specified address.
2290
2291    Corresponds to viPoke64 function of the VISA library.
2292
2293    Parameters
2294    ----------
2295    library : ctypes.WinDLL or ctypes.CDLL
2296        ctypes wrapped library.
2297    session : VISASession
2298        Unique logical identifier to a session.
2299    address : VISAMemoryAddress
2300        Source address to read the value.
2301    data : int
2302        Data to write.
2303
2304    Returns
2305    -------
2306    constants.StatusCode
2307        Return value of the library call.
2308
2309    """
2310    return library.viPoke64(session, address, data)
2311
2312
2313def read(library, session, count):
2314    """Reads data from device or interface synchronously.
2315
2316    Corresponds to viRead function of the VISA library.
2317
2318    Parameters
2319    ----------
2320    library : ctypes.WinDLL or ctypes.CDLL
2321        ctypes wrapped library.
2322    session : VISASession
2323        Unique logical identifier to a session.
2324    count : int
2325        Number of bytes to be read.
2326
2327    Returns
2328    -------
2329    bytes
2330        Date read
2331    constants.StatusCode
2332        Return value of the library call.
2333
2334    """
2335    buffer = create_string_buffer(count)
2336    return_count = ViUInt32()
2337    ret = library.viRead(session, buffer, count, byref(return_count))
2338    return buffer.raw[: return_count.value], ret
2339
2340
2341def read_stb(library, session):
2342    """Reads a status byte of the service request.
2343
2344    Corresponds to viReadSTB function of the VISA library.
2345
2346    Parameters
2347    ----------
2348    library : ctypes.WinDLL or ctypes.CDLL
2349        ctypes wrapped library.
2350    session : VISASession
2351        Unique logical identifier to a session.
2352
2353    Returns
2354    -------
2355    int
2356        Service request status byte
2357    constants.StatusCode
2358        Return value of the library call.
2359
2360    """
2361    status = ViUInt16()
2362    ret = library.viReadSTB(session, byref(status))
2363    return status.value, ret
2364
2365
2366def read_to_file(library, session, filename, count):
2367    """Read data synchronously, and store the transferred data in a file.
2368
2369    Corresponds to viReadToFile function of the VISA library.
2370
2371    Parameters
2372    ----------
2373    library : ctypes.WinDLL or ctypes.CDLL
2374        ctypes wrapped library.
2375    session : VISASession
2376        Unique logical identifier to a session.
2377    filename : str
2378        Name of file to which data will be written.
2379    count : int
2380        Number of bytes to be read.
2381
2382    Returns
2383    -------
2384    int
2385        Number of bytes actually transferred
2386    constants.StatusCode
2387        Return value of the library call.
2388
2389    """
2390    return_count = ViUInt32()
2391    ret = library.viReadToFile(session, filename, count, return_count)
2392    return return_count, ret
2393
2394
2395def set_attribute(library, session, attribute, attribute_state):
2396    """Set the state of an attribute.
2397
2398    Corresponds to viSetAttribute function of the VISA library.
2399
2400    Parameters
2401    ----------
2402    library : ctypes.WinDLL or ctypes.CDLL
2403        ctypes wrapped library.
2404    session : VISASession
2405        Unique logical identifier to a session.
2406    attribute : constants.ResourceAttribute
2407        Attribute for which the state is to be modified.
2408    attribute_state : Any
2409        The state of the attribute to be set for the specified object.
2410
2411    Returns
2412    -------
2413    constants.StatusCode
2414        Return value of the library call.
2415
2416    """
2417    return library.viSetAttribute(session, attribute, attribute_state)
2418
2419
2420def set_buffer(library, session, mask, size):
2421    """Set the size for the formatted I/O and/or low-level I/O communication buffer(s).
2422
2423    Corresponds to viSetBuf function of the VISA library.
2424
2425    Parameters
2426    ----------
2427    library : ctypes.WinDLL or ctypes.CDLL
2428        ctypes wrapped library.
2429    session : VISASession
2430        Unique logical identifier to a session.
2431    mask : constants.BufferType
2432        Specifies the type of buffer.
2433    size : int
2434        The size to be set for the specified buffer(s).
2435
2436    Returns
2437    -------
2438    constants.StatusCode
2439        Return value of the library call.
2440
2441    """
2442    return library.viSetBuf(session, mask, size)
2443
2444
2445def status_description(library, session, status):
2446    """Return a user-readable description of the status code passed to the operation.
2447
2448    Corresponds to viStatusDesc function of the VISA library.
2449
2450    Parameters
2451    ----------
2452    library : ctypes.WinDLL or ctypes.CDLL
2453        ctypes wrapped library.
2454    session : VISASession
2455        Unique logical identifier to a session.
2456    status : constants.StatusCode
2457        Status code to interpret.
2458
2459    Returns
2460    -------
2461    str
2462        User-readable string interpretation of the status code.
2463    constants.StatusCode
2464        Return value of the library call.
2465
2466    """
2467    description = create_string_buffer(256)
2468    ret = library.viStatusDesc(session, status, description)
2469    return buffer_to_text(description), ret
2470
2471
2472def terminate(library, session, degree, job_id):
2473    """Request a VISA session to terminate normal execution of an operation.
2474
2475    Corresponds to viTerminate function of the VISA library.
2476
2477    Parameters
2478    ----------
2479    library : ctypes.WinDLL or ctypes.CDLL
2480        ctypes wrapped library.
2481    session : VISASession
2482        Unique logical identifier to a session.
2483    degree : None
2484        Not used in this version of the VISA specification.
2485    job_id : VISAJobId
2486        Specifies an operation identifier. If a user passes None as the
2487        job_id value to viTerminate(), a VISA implementation should abort
2488        any calls in the current process executing on the specified vi.
2489        Any call that is terminated this way should return VI_ERROR_ABORT.
2490
2491    Returns
2492    -------
2493    constants.StatusCode
2494        Return value of the library call.
2495
2496    """
2497    return library.viTerminate(session, degree, job_id)
2498
2499
2500def uninstall_handler(library, session, event_type, handler, user_handle=None):
2501    """Uninstall handlers for events.
2502
2503    Corresponds to viUninstallHandler function of the VISA library.
2504
2505    Parameters
2506    ----------
2507    library : ctypes.WinDLL or ctypes.CDLL
2508        ctypes wrapped library.
2509    session : VISASession
2510        Unique logical identifier to a session.
2511    event_type : constants.EventType
2512        Logical event identifier.
2513    handler : VISAHandler
2514        Handler to be uninstalled by a client application.
2515    user_handle:
2516        A value specified by an application that can be used for
2517        identifying handlers uniquely in a session for an event.
2518        The modified value of the user_handle as returned by install_handler
2519        should be used instead of the original value.
2520
2521    Returns
2522    -------
2523    constants.StatusCode
2524        Return value of the library call.
2525
2526    """
2527    with set_user_handle_type(library, user_handle):
2528        if user_handle is not None:
2529            user_handle = byref(user_handle)
2530        return library.viUninstallHandler(session, event_type, handler, user_handle)
2531
2532
2533def unlock(library, session):
2534    """Relinquish a lock for the specified resource.
2535
2536    Corresponds to viUnlock function of the VISA library.
2537
2538    Parameters
2539    ----------
2540    library : ctypes.WinDLL or ctypes.CDLL
2541        ctypes wrapped library.
2542    session : VISASession
2543        Unique logical identifier to a session.
2544
2545    Returns
2546    -------
2547    constants.StatusCode
2548        Return value of the library call.
2549
2550    """
2551    return library.viUnlock(session)
2552
2553
2554def unmap_address(library, session):
2555    """Unmap memory space previously mapped by map_address().
2556
2557    Corresponds to viUnmapAddress function of the VISA library.
2558
2559    Parameters
2560    ----------
2561    library : ctypes.WinDLL or ctypes.CDLL
2562        ctypes wrapped library.
2563    session : VISASession
2564        Unique logical identifier to a session.
2565
2566    Returns
2567    -------
2568    constants.StatusCode
2569        Return value of the library call.
2570
2571    """
2572    return library.viUnmapAddress(session)
2573
2574
2575def unmap_trigger(library, session, trigger_source, trigger_destination):
2576    """Undo a previous map between a trigger source line and a destination line.
2577
2578    Corresponds to viUnmapTrigger function of the VISA library.
2579
2580    Parameters
2581    ----------
2582    library : ctypes.WinDLL or ctypes.CDLL
2583        ctypes wrapped library.
2584    session : VISASession
2585        Unique logical identifier to a session.
2586    trigger_source : constants.InputTriggerLine
2587        Source line used in previous map.
2588    trigger_destination : constants.OutputTriggerLine
2589        Destination line used in previous map.
2590
2591    Returns
2592    -------
2593    constants.StatusCode
2594        Return value of the library call.
2595
2596    """
2597    return library.viUnmapTrigger(session, trigger_source, trigger_destination)
2598
2599
2600def usb_control_in(
2601    library,
2602    session,
2603    request_type_bitmap_field,
2604    request_id,
2605    request_value,
2606    index,
2607    length=0,
2608):
2609    """Perform a USB control pipe transfer from the device.
2610
2611    Corresponds to viUsbControlIn function of the VISA library.
2612
2613    Parameters
2614    ----------
2615    library : ctypes.WinDLL or ctypes.CDLL
2616        ctypes wrapped library.
2617    session : VISASession
2618        Unique logical identifier to a session.
2619    request_type_bitmap_field : int
2620        bmRequestType parameter of the setup stage of a USB control transfer.
2621    request_id : int
2622        bRequest parameter of the setup stage of a USB control transfer.
2623    request_value : int
2624        wValue parameter of the setup stage of a USB control transfer.
2625    index : int
2626        wIndex parameter of the setup stage of a USB control transfer.
2627        This is usually the index of the interface or endpoint.
2628    length : int, optional
2629        wLength parameter of the setup stage of a USB control transfer.
2630        This value also specifies the size of the data buffer to receive
2631        the data from the optional data stage of the control transfer.
2632
2633    Returns
2634    -------
2635    bytes
2636        The data buffer that receives the data from the optional data stage
2637        of the control transfer
2638    constants.StatusCode
2639        Return value of the library call.
2640
2641    """
2642    buffer = create_string_buffer(length)
2643    return_count = ViUInt16()
2644    ret = library.viUsbControlIn(
2645        session,
2646        request_type_bitmap_field,
2647        request_id,
2648        request_value,
2649        index,
2650        length,
2651        buffer,
2652        byref(return_count),
2653    )
2654    return buffer.raw[: return_count.value], ret
2655
2656
2657def usb_control_out(
2658    library,
2659    session,
2660    request_type_bitmap_field,
2661    request_id,
2662    request_value,
2663    index,
2664    data="",
2665):
2666    """Perform a USB control pipe transfer to the device.
2667
2668    Corresponds to viUsbControlOut function of the VISA library.
2669
2670    Parameters
2671    ----------
2672    library : ctypes.WinDLL or ctypes.CDLL
2673        ctypes wrapped library.
2674    session : VISASession
2675        Unique logical identifier to a session.
2676    request_type_bitmap_field : int
2677        bmRequestType parameter of the setup stage of a USB control transfer.
2678    request_id : int
2679        bRequest parameter of the setup stage of a USB control transfer.
2680    request_value : int
2681        wValue parameter of the setup stage of a USB control transfer.
2682    index : int
2683        wIndex parameter of the setup stage of a USB control transfer.
2684        This is usually the index of the interface or endpoint.
2685    data : bytes, optional
2686        The data buffer that sends the data in the optional data stage of
2687        the control transfer.
2688
2689    Returns
2690    -------
2691    constants.StatusCode
2692        Return value of the library call.
2693
2694    """
2695    length = len(data)
2696    return library.viUsbControlOut(
2697        session,
2698        request_type_bitmap_field,
2699        request_id,
2700        request_value,
2701        index,
2702        length,
2703        data,
2704    )
2705
2706
2707def vxi_command_query(library, session, mode, command):
2708    """Send the device a miscellaneous command or query and/or retrieves the response to a previous query.
2709
2710    Corresponds to viVxiCommandQuery function of the VISA library.
2711
2712    Parameters
2713    ----------
2714    library : ctypes.WinDLL or ctypes.CDLL
2715        ctypes wrapped library.
2716    session : VISASession
2717        Unique logical identifier to a session.
2718    mode : constants.VXICommands
2719        Specifies whether to issue a command and/or retrieve a response.
2720    command : int
2721        The miscellaneous command to send.
2722
2723    Returns
2724    -------
2725    int
2726        The response retrieved from the device
2727    constants.StatusCode
2728        Return value of the library call.
2729
2730    """
2731    response = ViUInt32()
2732    ret = library.viVxiCommandQuery(session, mode, command, byref(response))
2733    return response.value, ret
2734
2735
2736def wait_on_event(library, session, in_event_type, timeout):
2737    """Wait for an occurrence of the specified event for a given session.
2738
2739    Corresponds to viWaitOnEvent function of the VISA library.
2740
2741    Parameters
2742    ----------
2743    library : ctypes.WinDLL or ctypes.CDLL
2744        ctypes wrapped library.
2745    session : VISASession
2746        Unique logical identifier to a session.
2747    in_event_type : constants.EventType
2748        Logical identifier of the event(s) to wait for.
2749    timeout : int
2750        Absolute time period in time units that the resource shall wait for
2751        a specified event to occur before returning the time elapsed error.
2752        The time unit is in milliseconds.
2753
2754    Returns
2755    -------
2756    constants.EventType
2757        Logical identifier of the event actually received
2758    VISAEventContext
2759        A handle specifying the unique occurrence of an event
2760    constants.StatusCode
2761        Return value of the library call.
2762
2763    """
2764    out_event_type = ViEventType()
2765    out_context = ViEvent()
2766    ret = library.viWaitOnEvent(
2767        session, in_event_type, timeout, byref(out_event_type), byref(out_context)
2768    )
2769    return out_event_type.value, out_context, ret
2770
2771
2772def write(library, session, data):
2773    """Write data to device or interface synchronously.
2774
2775    Corresponds to viWrite function of the VISA library.
2776
2777    Parameters
2778    ----------
2779    library : ctypes.WinDLL or ctypes.CDLL
2780        ctypes wrapped library.
2781    session : VISASession
2782        Unique logical identifier to a session.
2783    data : bytes
2784        Data to be written.
2785
2786    Returns
2787    -------
2788    int
2789        Number of bytes actually transferred
2790    constants.StatusCode
2791        Return value of the library call.
2792
2793    """
2794    return_count = ViUInt32()
2795    # [ViSession, ViBuf, ViUInt32, ViPUInt32]
2796    ret = library.viWrite(session, data, len(data), byref(return_count))
2797    return return_count.value, ret
2798
2799
2800def write_asynchronously(library, session, data):
2801    """Write data to device or interface asynchronously.
2802
2803    Corresponds to viWriteAsync function of the VISA library.
2804
2805    Parameters
2806    ----------
2807    library : ctypes.WinDLL or ctypes.CDLL
2808        ctypes wrapped library.
2809    session : VISASession
2810        Unique logical identifier to a session.
2811    data : bytes
2812        Data to be written.
2813
2814    Returns
2815    -------
2816    VISAJobID
2817        Job ID of this asynchronous write operation
2818    constants.StatusCode
2819        Return value of the library call.
2820
2821    """
2822    job_id = ViJobId()
2823    # [ViSession, ViBuf, ViUInt32, ViPJobId]
2824    ret = library.viWriteAsync(session, data, len(data), byref(job_id))
2825    return job_id, ret
2826
2827
2828def write_from_file(library, session, filename, count):
2829    """Take data from a file and write it out synchronously.
2830
2831    Corresponds to viWriteFromFile function of the VISA library.
2832
2833    Parameters
2834    ----------
2835    library : ctypes.WinDLL or ctypes.CDLL
2836        ctypes wrapped library.
2837    session : VISASession
2838        Unique logical identifier to a session.
2839    filename : str
2840        Name of file from which data will be read.
2841    count : int
2842        Number of bytes to be written.
2843
2844    Returns
2845    -------
2846    int
2847        Number of bytes actually transferred
2848    constants.StatusCode
2849        Return value of the library call.
2850
2851    """
2852    return_count = ViUInt32()
2853    ret = library.viWriteFromFile(session, filename, count, return_count)
2854    return return_count, ret
2855