Skip to content

Commit

Permalink
Merge branch 'lupien-improve_handlers'
Browse files Browse the repository at this point in the history
  • Loading branch information
hgrecco committed Apr 23, 2015
2 parents 8dd5611 + 944e67e commit 2526845
Show file tree
Hide file tree
Showing 4 changed files with 103 additions and 22 deletions.
47 changes: 47 additions & 0 deletions pyvisa/constants.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@

import enum

from .compat import PYTHON3

if PYTHON3:
LongEnum = enum.IntEnum
else:
class LongEnum(long, enum.Enum):
pass

# _to_int() is necessary because the VISA specification is flawed: It defines
# the VISA codes, which have a value less than zero, in their internal 32-bit
# signed integer representation. However, this is positive. ctypes doesn't
Expand Down Expand Up @@ -299,6 +307,7 @@ def _to_int(x):
VI_EVENT_VXI_VME_SYSRESET = 0x3FFF201E
VI_EVENT_VXI_SIGP = 0x3FFF2020
VI_EVENT_VXI_VME_INTR = 0xBFFF2021
VI_EVENT_PXI_INTR = 0x3FFF2022
VI_EVENT_TCPIP_CONNECT = 0x3FFF2036
VI_EVENT_USB_INTR = 0x3FFF2037

Expand Down Expand Up @@ -705,6 +714,44 @@ class LineState(enum.IntEnum):
unknown = VI_STATE_UNKNOWN


class EventMechanism(enum.IntEnum):
"""The available event mechanisms for event handling.
"""

queue = VI_QUEUE
handler = VI_HNDLR

#: events queued but handler not called
suspend_handler = VI_SUSPEND_HNDLR

all = VI_ALL_MECH


# Note that enum.IntEnum fails here for python2:
# OverflowError: Python int too large to convert to C long
# so use LongEnum instead (some values are too large, and ViEventType is unsigned)
class EventType(LongEnum):
"""The available event types for event handling.
"""

io_completion = VI_EVENT_IO_COMPLETION
trig = VI_EVENT_TRIG
service_request = VI_EVENT_SERVICE_REQ
clear = VI_EVENT_CLEAR
exception = VI_EVENT_EXCEPTION
gpib_controller_in_charge = VI_EVENT_GPIB_CIC
gpib_talk = VI_EVENT_GPIB_TALK
gpib_listen = VI_EVENT_GPIB_LISTEN
vxi_vme_sysfail = VI_EVENT_VXI_VME_SYSFAIL
vxi_vme_sysreset = VI_EVENT_VXI_VME_SYSRESET
vxi_signal_interrupt = VI_EVENT_VXI_SIGP
vxi_vme_interrupt = VI_EVENT_VXI_VME_INTR
pxi_interrupt = VI_EVENT_PXI_INTR
tcpip_connect = VI_EVENT_TCPIP_CONNECT
usb_interrupt = VI_EVENT_USB_INTR
all_enabled = VI_ALL_ENABLED_EVENTS


class StatusCode(enum.IntEnum):
"""Specifies the status codes that NI-VISA driver-level operations can return.
"""
Expand Down
28 changes: 18 additions & 10 deletions pyvisa/ctwrapper/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ def disable_event(library, session, event_type, mechanism):
:param session: Unique logical identifier to a session.
:param event_type: Logical event identifier.
:param mechanism: Specifies event handling mechanisms to be disabled.
(Constants.QUEUE, .Handler, .SUSPEND_HNDLR, .ALL_MECH)
(Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR, .VI_ALL_MECH)
:return: return value of the library call.
:rtype: :class:`pyvisa.constants.StatusCode`
"""
Expand All @@ -414,8 +414,8 @@ def discard_events(library, session, event_type, mechanism):
:param library: the visa library wrapped by ctypes.
:param session: Unique logical identifier to a session.
:param event_type: Logical event identifier.
:param mechanism: Specifies event handling mechanisms to be disabled.
(Constants.QUEUE, .Handler, .SUSPEND_HNDLR, .ALL_MECH)
:param mechanism: Specifies event handling mechanisms to be dicarded.
(Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR, .VI_ALL_MECH)
:return: return value of the library call.
:rtype: :class:`pyvisa.constants.StatusCode`
"""
Expand All @@ -430,8 +430,8 @@ def enable_event(library, session, event_type, mechanism, context=None):
:param library: the visa library wrapped by ctypes.
:param session: Unique logical identifier to a session.
:param event_type: Logical event identifier.
:param mechanism: Specifies event handling mechanisms to be disabled.
(Constants.QUEUE, .Handler, .SUSPEND_HNDLR)
:param mechanism: Specifies event handling mechanisms to be enabled.
(Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR)
:param context:
:return: return value of the library call.
:rtype: :class:`pyvisa.constants.StatusCode`
Expand Down Expand Up @@ -727,7 +727,8 @@ def install_handler(library, session, event_type, handler, user_handle):
:param event_type: Logical event identifier.
:param handler: Interpreted as a valid reference to a handler to be installed by a client application.
:param user_handle: A value specified by an application that can be used for identifying handlers
uniquely for an event type.
uniquely for an event type. Can be a regular python object (int, float, str, list
of floats or ints) or a ctypes object.
:returns: a handler descriptor which consists of three elements:
- handler (a python callable)
- user handle (a ctypes object)
Expand All @@ -754,7 +755,12 @@ def install_handler(library, session, event_type, handler, user_handle):
converted_user_handle = \
(c_long * len(user_handle))(*tuple(user_handle))
else:
raise TypeError("Type not allowed as user handle: %s" % type(user_handle))
try:
# check if it is already a ctypes
byref(user_handle)
converted_user_handle = user_handle
except TypeError:
raise TypeError("Type not allowed as user handle: %s" % type(user_handle))

set_user_handle_type(library, converted_user_handle)
converted_handler = ViHndlr(handler)
Expand Down Expand Up @@ -1696,12 +1702,14 @@ def uninstall_handler(library, session, event_type, handler, user_handle=None):
:param session: Unique logical identifier to a session.
:param event_type: Logical event identifier.
:param handler: Interpreted as a valid reference to a handler to be uninstalled by a client application.
:param user_handle: A value specified by an application that can be used for identifying handlers
uniquely in a session for an event.
:param user_handle: The user_handle (a ctypes object) in the returned value from install_handler.
:return: return value of the library call.
:rtype: :class:`pyvisa.constants.StatusCode`
"""
return library.viUninstallHandler(session, event_type, handler, byref(user_handle))
set_user_handle_type(library, user_handle)
if user_handle != None:
user_handle = byref(user_handle)
return library.viUninstallHandler(session, event_type, handler, user_handle)


def unlock(library, session):
Expand Down
15 changes: 7 additions & 8 deletions pyvisa/highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def install_visa_handler(self, session, event_type, handler, user_handle=None):
except TypeError as e:
raise errors.VisaTypeError(str(e))

self.handlers[session].append(new_handler)
self.handlers[session].append(new_handler + (event_type,))
return new_handler[1]

def uninstall_visa_handler(self, session, event_type, handler, user_handle=None):
Expand All @@ -191,16 +191,15 @@ def uninstall_visa_handler(self, session, event_type, handler, user_handle=None)
:param session: Unique logical identifier to a session.
:param event_type: Logical event identifier.
:param handler: Interpreted as a valid reference to a handler to be uninstalled by a client application.
:param user_handle: A value specified by an application that can be used for identifying handlers
uniquely in a session for an event.
:param user_handle: The user handle (ctypes object or None) returned by install_visa_handler.
"""
for ndx, element in enumerate(self.handlers[session]):
if element[0] is handler and element[1] is user_handle:
if element[0] is handler and element[1] is user_handle and element[4] == event_type:
del self.handlers[session][ndx]
break
else:
raise errors.UnknownHandler(event_type, handler, user_handle)
self.uninstall_handler(session, event_type, handler, user_handle)
self.uninstall_handler(session, event_type, element[2], user_handle)

def read_memory(self, session, space, offset, width, extended=False):
"""Reads in an 8-bit, 16-bit, 32-bit, or 64-bit value from the specified memory space and offset.
Expand Down Expand Up @@ -454,8 +453,8 @@ def discard_events(self, session, event_type, mechanism):
:param session: Unique logical identifier to a session.
:param event_type: Logical event identifier.
:param mechanism: Specifies event handling mechanisms to be disabled.
(Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR, .VI_SUSPEND_HNDLR)
:param mechanism: Specifies event handling mechanisms to be discarded.
(Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR, .VI_ALL_MECH)
:return: return value of the library call.
:rtype: :class:`pyvisa.constants.StatusCode`
"""
Expand All @@ -468,7 +467,7 @@ def enable_event(self, session, event_type, mechanism, context=None):
:param session: Unique logical identifier to a session.
:param event_type: Logical event identifier.
:param mechanism: Specifies event handling mechanisms to be disabled.
:param mechanism: Specifies event handling mechanisms to be enabled.
(Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR)
:param context:
:return: return value of the library call.
Expand Down
35 changes: 31 additions & 4 deletions pyvisa/resources/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -236,18 +236,45 @@ def install_handler(self, event_type, handler, user_handle=None):
:returns: user handle (a ctypes object)
"""

return self.visalib.install_handler(self.session, event_type, handler, user_handle)[:-1]
return self.visalib.install_visa_handler(self.session, event_type, handler, user_handle)

def uninstall_handler(self, event_type, handler, user_handle=None):
"""Uninstalls handlers for events in this resource.
:param event_type: Logical event identifier.
:param handler: Interpreted as a valid reference to a handler to be uninstalled by a client application.
:param user_handle: A value specified by an application that can be used for identifying handlers
uniquely in a session for an event.
:param user_handle: The user handle (ctypes object or None) returned by install_handler.
"""

self.visalib.uninstall_handler(self.session, event_type, handler, user_handle)
self.visalib.uninstall_visa_handler(self.session, event_type, handler, user_handle)

def disable_event(self, event_type, mechanism):
"""Disables notification of the specified event type(s) via the specified mechanism(s).
:param event_type: Logical event identifier.
:param mechanism: Specifies event handling mechanisms to be disabled.
(Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR, .VI_ALL_MECH)
"""
self.visalib.disable_event(self.session, event_type, mechanism)

def discard_events(self, event_type, mechanism):
"""Discards event occurrences for specified event types and mechanisms in this resource.
:param event_type: Logical event identifier.
:param mechanism: Specifies event handling mechanisms to be dicarded.
(Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR, .VI_ALL_MECH)
"""
self.visalib.discard_events(self.session, event_type, mechanism)

def enable_event(self, event_type, mechanism, context=None):
"""Enable event occurrences for specified event types and mechanisms in this resource.
:param event_type: Logical event identifier.
:param mechanism: Specifies event handling mechanisms to be enabled.
(Constants.VI_QUEUE, .VI_HNDLR, .VI_SUSPEND_HNDLR)
:param context: Not currently used, leave as None.
"""
self.visalib.enable_event(self.session, event_type, mechanism, context)

def lock(self, timeout=None, requested_key=None):
"""Establish a shared lock to the resource.
Expand Down

0 comments on commit 2526845

Please sign in to comment.