Skip to content

Commit

Permalink
Merge branch 'lupien-improve_handlers2'
Browse files Browse the repository at this point in the history
  • Loading branch information
hgrecco committed May 10, 2015
2 parents c25f16a + a791c6b commit c22c0bf
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 24 deletions.
17 changes: 17 additions & 0 deletions pyvisa/highlevel.py
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,23 @@ def uninstall_visa_handler(self, session, event_type, handler, user_handle=None)
raise errors.UnknownHandler(event_type, handler, user_handle)
self.uninstall_handler(session, event_type, element[2], user_handle)

def __uninstall_all_handlers_helper(self, session):
for element in self.handlers[session]:
self.uninstall_handler(session, element[4], element[2], element[1])
del self.handlers[session]

def uninstall_all_visa_handlers(self, session):
"""Uninstalls all previously installed handlers for a particular session.
:param session: Unique logical identifier to a session. If None, operates on all sessions.
"""

if session is not None:
self.__uninstall_all_handlers_helper(session)
else:
for session in list(self.handlers):
self.__uninstall_all_handlers_helper(session)

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
28 changes: 5 additions & 23 deletions pyvisa/resources/gpib.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,12 +24,6 @@ class _GPIBMixin(object):
"""Common attributes and methods of GPIB Instr and Interface.
"""

def assert_trigger(self):
"""Sends a software trigger to the device.
"""

self.visalib.assert_trigger(self.session, constants.VI_TRIG_PROT_DEFAULT)

def send_command(self, data):
"""Write GPIB command bytes on the bus.
Expand Down Expand Up @@ -102,27 +96,17 @@ class GPIBInstrument(_GPIBMixin, MessageBasedResource):
Do not instantiate directly, use :meth:`pyvisa.highlevel.ResourceManager.open_resource`.
"""

def before_close(self):
self.__switch_events_off()
super(GPIBInstrument, self).before_close()

def __switch_events_off(self):
self.visalib.disable_event(self.session, constants.VI_ALL_ENABLED_EVENTS, constants.VI_ALL_MECH)
self.visalib.discard_events(self.session, constants.VI_ALL_ENABLED_EVENTS, constants.VI_ALL_MECH)

def wait_for_srq(self, timeout=25000):
"""Wait for a serial request (SRQ) coming from the instrument.
Note that this method is not ended when *another* instrument signals an
SRQ, only *this* instrument.
:param timeout: the maximum waiting time in milliseconds.
Defaul: 25000 (seconds).
Defaul: 25000 (milliseconds).
None means waiting forever if necessary.
"""
lib = self.visalib

lib.enable_event(self.session, constants.VI_EVENT_SERVICE_REQ, constants.VI_QUEUE)
self.enable_event(constants.VI_EVENT_SERVICE_REQ, constants.VI_QUEUE)

if timeout and not(0 <= timeout <= 4294967295):
raise ValueError("timeout value is invalid")
Expand All @@ -133,17 +117,15 @@ def wait_for_srq(self, timeout=25000):
if timeout is None:
adjusted_timeout = constants.VI_TMO_INFINITE
else:
adjusted_timeout = int((starting_time + timeout - time.clock()))
adjusted_timeout = int((starting_time + timeout/1e3 - time.clock())*1e3)
if adjusted_timeout < 0:
adjusted_timeout = 0

event_type, context, error = lib.wait_on_event(self.session, constants.VI_EVENT_SERVICE_REQ,
adjusted_timeout)
lib.close(context)
self.wait_on_event(constants.VI_EVENT_SERVICE_REQ, adjusted_timeout)
if self.stb & 0x40:
break

lib.discard_events(self.session, constants.VI_EVENT_SERVICE_REQ, constants.VI_QUEUE)
self.discard_events(constants.VI_EVENT_SERVICE_REQ, constants.VI_QUEUE)


@Resource.register(constants.InterfaceType.gpib, 'INTFC')
Expand Down
40 changes: 39 additions & 1 deletion pyvisa/resources/resource.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,20 @@
from .. import attributes


class WaitResponse(object):
"""Class used in return of wait_on_event. It properly closes the context upon delete.
"""
def __init__(self, event_type, context, ret, visalib, timed_out=False):
self.event_type = constants.EventType(event_type)
self.context = context
self.ret = ret
self._visalib = visalib
self.timed_out = timed_out
def __del__(self):
if self.context != None:
self._visalib.close(self.context)


class Resource(object):
"""Base class for resources.
Expand Down Expand Up @@ -193,7 +207,7 @@ def open(self, access_mode=constants.AccessModes.no_lock, open_timeout=5000):
def before_close(self):
"""Called just before closing an instrument.
"""
pass
self.__switch_events_off()

def close(self):
"""Closes the VISA session and marks the handle as invalid.
Expand All @@ -209,6 +223,11 @@ def close(self):
except errors.InvalidSession:
pass

def __switch_events_off(self):
self.disable_event(constants.VI_ALL_ENABLED_EVENTS, constants.VI_ALL_MECH)
self.discard_events(constants.VI_ALL_ENABLED_EVENTS, constants.VI_ALL_MECH)
self.visalib.uninstall_all_visa_handlers(self.session)

def get_visa_attribute(self, name):
"""Retrieves the state of an attribute in this resource.
Expand Down Expand Up @@ -281,6 +300,25 @@ def enable_event(self, event_type, mechanism, context=None):
"""
self.visalib.enable_event(self.session, event_type, mechanism, context)

def wait_on_event(self, in_event_type, timeout, capture_timeout=False):
"""Waits for an occurrence of the specified event in this resource.
:param in_event_type: Logical identifier of the event(s) to wait for.
:param timeout: Absolute time period in time units that the resource shall wait for a specified event to
occur before returning the time elapsed error. The time unit is in milliseconds.
None means waiting forever if necessary.
:param capture_timeout: When True will not produce a VisaIOError(VI_ERROR_TMO) but
instead return a WaitResponse with timed_out=True
:return: A WaitResponse object that contains event_type, context and ret value.
"""
try:
event_type, context, ret = self.visalib.wait_on_event(self.session, in_event_type, timeout)
except errors.VisaIOError as exc:
if capture_timeout and exc.error_code == constants.StatusCode.error_timeout:
return WaitResponse(0, None, exc.error_code, self.visalib, timed_out=True)
raise
return WaitResponse(event_type, context, ret, self.visalib)

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

0 comments on commit c22c0bf

Please sign in to comment.