Source code for digitalIn

from pypixxlib.schedule import Schedule
from abc import ABCMeta

from pypixxlib._libdpx import DPxGetDinNumBits, DPxGetDinValue, \
    DPxSetDinDataDir, DPxGetDinDataDir, DPxSetDinDataOut, DPxGetDinDataOut, \
    DPxSetDinDataOutStrength, DPxGetDinDataOutStrength, DPxEnableDinStabilize, \
    DPxDisableDinStabilize, DPxIsDinStabilize, DPxEnableDinDebounce, \
    DPxDisableDinDebounce, DPxIsDinDebounce, DPxEnableDoutDinLoopback, \
    DPxDisableDoutDinLoopback, DPxIsDoutDinLoopback, DPxSetDinBuffBaseAddr, \
    DPxGetDinBuffBaseAddr, DPxSetDinBuffWriteAddr, DPxGetDinBuffWriteAddr, \
    DPxSetDinBuffSize, DPxGetDinBuffSize, DPxSetDinSchedOnset, \
    DPxGetDinSchedOnset, DPxSetDinSchedRate, DPxGetDinSchedRate, \
    DPxSetDinSchedCount, DPxGetDinSchedCount, DPxEnableDinSchedCountdown, \
    DPxDisableDinSchedCountdown, DPxIsDinSchedCountdown, DPxStartDinSched, \
    DPxStopDinSched, DPxIsDinSchedRunning, \
    DPxEnableDinLogTimetags, DPxDisableDinLogTimetags, DPxIsDinLogTimetags, \
    DPxEnableDinLogEvents, DPxDisableDinLogEvents, DPxIsDinLogEvents, \
    DPxReadDinLog, DPxGetDinStatus, DPxDisableDinLogEvents, DPxStartDinLog, DPxSetDinLog

from pypixxlib.dpxDevice import DpxExceptionDecorate

[docs]class DigitalIn(Schedule, metaclass=ABCMeta): """Class which implements the DIN features. Any device which has Digital IN should implement this Class. It contains all the necessary methods to use the digital inputs of a VPixx device. """ @DpxExceptionDecorate def __init__(self): pass
[docs] @DpxExceptionDecorate def getNbrOfBit(self): """Gets the number of bit available. Returns: int: Number of bits. """ return DPxGetDinNumBits()
[docs] @DpxExceptionDecorate def getValue(self): """Gets the current value of the bits. Returns: int: Value of bits. """ return DPxGetDinValue()
[docs] @DpxExceptionDecorate def setBitDirection(self, bit_mask): """Sets the port direction mask. Sets the port direction for each bit. The mask is one value representing all bits from the port. The given ``bit_mask`` will set the direction of all digital input bits. For each bit which should drive its port, the corresponding ``bit_mask`` value should be set to 1. An hexadecimal ``bit_mask`` can be provided. For example, ``bit_mask = 0x0000F`` will enable the port for the first 4 bits on the right. All other ports will be disabled. User can then use the first 4 bits to drive the port. Args: int: Set bit to 1 to enable the port for that bit. Set bit to 0 to disable it. """ DPxSetDinDataDir(bit_mask)
[docs] @DpxExceptionDecorate def getBitDirection(self): """Gets the port direction mask. User can obtain the value in decimal or hexadecimal. Returns: int: Bit set to 1 is an enabled port. Bit set to 0 is a disabled port. """ return DPxGetDinDataDir()
[docs] @DpxExceptionDecorate def setOutputValue(self, value): """Sets the data which should be driven on each port. In order to be able to drive the ports with the given value, the port direction has to be properly enabled. This can be done using the "setBitDirection()" with the appropriate bit mask. Args: value (int): Any value in a range of 0 to 16777215. """ DPxSetDinDataOut( int(value, 0) )
[docs] @DpxExceptionDecorate def getOutputValue(self): """Gets the data which is being driven on each output port. This method allows the user to get the data which is currently driven on the output port. Returns: int: Any value in a range of 0 to 16777215. """ return DPxGetDinDataOut()
[docs] @DpxExceptionDecorate def setOutputStrength(self, strength): """Sets the strength of the driven outputs. This method allows the user to set the current (Ampere) strength of the driven outputs. The implementation actual values uses ``1/16`` up to ``16/16``. So minimum strength will be ``0.0625`` and maximum will be ``1``. The strength can be increased by ``0.0625`` up to ``1``. Giving a strength of ``0`` will thus set it to ``0.0625``. Giving a strength between ``0.0625`` and ``0.125`` will round the given strength to one of the two increments. The strength is the same for all bits. Args: strength (float): Any value in a range of 0 to 1. """ DPxSetDinDataOutStrength(strength)
[docs] @DpxExceptionDecorate def getOutputStrength(self): """Gets the strength of the driven outputs. This method allows the user to get the strength currently driven by the outputs. The implementation uses values from ``1/16`` up to ``16/16``. Therefore minimum strength will be ``0.0625`` and maximum will be ``1``. The strength can be increased by ``0.0625`` up to ``1``. Returns: float: Any value in a range of 0 to 1. """ return DPxGetDinDataOutStrength()
[docs] @DpxExceptionDecorate def setStabilize(self, enable): """Sets the input stabilization mode. This method allows the user to enable or disable the input transitions stabilization. When enabled, input transitions are only recognized after the entire input bus has been stable for 80 ns. This is useful for deskewing parallel busses, and ignoring transmission line reflections. When disabled, the input transitions are immediately recognized. In which case, it can be useful to enable debouncing using ``setDebounce()``. Args: enable (Bool): True if transitions are being stabilized, False otherwise. """ if enable == True: DPxEnableDinStabilize() else: DPxDisableDinStabilize()
[docs] @DpxExceptionDecorate def isStabilizeEnabled(self): """Verifies if the input transitions are being stabilized. Returns: stabilize (Bool): True if transitions are being stabilized, False otherwise. """ if DPxIsDinStabilize() == 0: stabilize = False else: stabilize = True return stabilize
[docs] @DpxExceptionDecorate def setDebounce(self, enable): """Sets the input debounce mode. This method allows the user to enable or disable the input debounce mode. When a DIN transitions, ignore further DIN transitions for the next 30 milliseconds. This is useful for response buttons. When disabled, the inputs transitions are immediately recognized. In which case, it can be useful to enable debouncing using ``setStabilize()``. Args: enable (Bool): True if transitions are being debounced, False otherwise. """ if enable == True: DPxEnableDinDebounce() else: DPxDisableDinDebounce()
[docs] @DpxExceptionDecorate def isDebounceEnabled(self): """Verifies if the input debounce mode is enabled. Returns: debouce (Bool): True if transitions are being stabilized, False otherwise. """ if DPxIsDinDebounce() == 0: debouce = False else: debouce = True return debouce
[docs] @DpxExceptionDecorate def setLoopback(self, enable): """Sets the digital inputs and outputs loopback mode. This method allows the user to enable or disable the loopback between digital output ports and digital inputs. When enabled, the digital outputs send their data to the digital inputs. When disabled, the digital inputs will not get the digital outputs data. debouncing using "setStabilize()". Args: enable (Bool): True if loopback is enabled, False otherwise. See Also: :class:`isLoopbackEnabled` """ if enable == True: DPxEnableDoutDinLoopback() else: DPxDisableDoutDinLoopback()
[docs] @DpxExceptionDecorate def isLoopbackEnabled(self): """Verifies the digital inputs and outputs loopback mode. Returns: enable (Bool): True if transitions are being stabilized, False otherwise. See Also: :class:`setLoopback` """ if DPxIsDoutDinLoopback() == 0: enable = False else: enable = True return enable
[docs] @DpxExceptionDecorate def setBaseAddress(self, address): """Sets the Ram buffer start address. This method allows the user to set the RAM buffer start address used in schedules. The given address must be an even value. Args: address (int): Any value in a range of 0 up to the RAM size. """ DPxSetDinBuffBaseAddr(address)
[docs] @DpxExceptionDecorate def getBaseAddress(self): """Gets the Ram buffer start address. This method allows the user to get the RAM buffer start address used in schedules. It should only be used if the user wants the schedules to wrap when it has reached its maximum size. When schedules are expected to wrap, the user should also use setBufferSize(). Returns: int: Any value in a range of 0 up to the RAM size. """ return DPxGetDinBuffBaseAddr()
[docs] @DpxExceptionDecorate def setWriteAddress(self, address): """Sets the Ram buffer write address. This method allows the user to set the RAM buffer write address used in schedules. This address is used by the schedule to know where the data should be first written to. The schedule will then write the following data to the address following the RAM buffer write address. The given address must be an even value. Args: address (int): Any value in a range of 0 up to the RAM size. """ DPxSetDinBuffWriteAddr(address)
[docs] @DpxExceptionDecorate def getWriteAddress(self): """Gets the Ram buffer write address. This method allows the user to get the RAM buffer write address used in schedules. Returns: int: Any value in a range of 0 up to the RAM size. """ return DPxGetDinBuffWriteAddr()
[docs] @DpxExceptionDecorate def setBufferSize(self, buffer_size): """Sets the Ram buffer size. This method allows the user to set the RAM buffer size used in schedules. It should only be used if the user wants the schedule to wrap when it has reached its maximum size. When schedules are expected to wrap, the user should also use ``setBaseAddress()``. The given size is in bytes and must be an even value. Args: buffer_size (int): Any value in a range of 0 up to the RAM size. """ DPxSetDinBuffSize(buffer_size)
[docs] @DpxExceptionDecorate def getBufferSize(self): """Gets the Ram buffer size. This method allows the user to get the RAM buffer size used in schedules. Returns: int: Any value in a range of 0 up to the RAM size. """ return DPxGetDinBuffSize()
[docs] @DpxExceptionDecorate def setScheduleOnset(self, onset): """Sets the schedule onset value. This method allows the user to set the nanosecond delay between schedule start and first sample. If no delay is required, this method does not need to be used. Default value is 0. Args: onset (int): Any positive value equal to or greater than 0. See Also: :class:`getScheduleOnset` """ DPxSetDinSchedOnset(onset)
[docs] @DpxExceptionDecorate def getScheduleOnset(self): """Gets the schedule onset value. This method allows the user to get the schedule onset value used in schedules. The onset represents a nanosecond delay between schedule start and first sample. Returns: int: Any positive value equal to or greater than 0. See Also: :class:`setScheduleOnset` """ return DPxGetDinSchedOnset()
[docs] @DpxExceptionDecorate def setScheduleRate(self, rate, unit='hz'): """Sets the schedule rate. This method allows the user to set the schedule rate. Since the rate can be given with different units, the method also needs to have a unit associated with the rate. Args: rate (int): Any positive value equal to or greater than 0. unit (str): hz : samples per second, maximum 1 MHz. video : samples per video frame, maximum 1 MHz. nano : sample period in nanoseconds, minimum 1000 ns. See Also: :class:`getScheduleRate`, :class:`getScheduleUnit` """ DPxSetDinSchedRate(rate, unit)
[docs] @DpxExceptionDecorate def getScheduleRate(self): """Gets the schedule rate value. This method allows the user to get the schedule rate value used in schedules. The rate represents the speed at which the schedule updates. Returns: int: Any positive value equal to or greater than 0. See Also: :class:`setScheduleRate`, :class:`getScheduleUnit` """ schedule_rate = DPxGetDinSchedRate() return schedule_rate[0]
[docs] @DpxExceptionDecorate def getScheduleUnit(self): """Gets the schedule unit value. This method allows the user to get the schedule unit value used in schedules. Returns: int: Any positive value equal to or greater than 0. See Also: :class:`getScheduleRate`, :class:`setScheduleRate` """ schedule_unit = DPxGetDinSchedRate() return schedule_unit[1]
[docs] @DpxExceptionDecorate def setScheduleCount(self, count): """Sets the schedule count. This method allows the user to set the schedule count for a schedule with a fixed number of sample. In which case, the schedule will decrement at a given rate and stop when the count reaches 0. Args: count (int): Any positive value greater than 0. See Also: :class:`getScheduleCount`, :class:`setScheduleCountDown` """ DPxSetDinSchedCount(count)
[docs] @DpxExceptionDecorate def getScheduleCount(self): """Gets the schedule count value. This method allows the user to get the current count for a schedule. Returns: int: Any positive value equal to or greater than 0. See Also: :class:`setScheduleCount`, :class:`setScheduleCountDown` """ return DPxGetDinSchedCount()
[docs] @DpxExceptionDecorate def setScheduleCountDown(self, enable): """Sets the schedule count down mode. This method allows the user to enable or disable the count down on a schedule. When enabled, the schedule decrements at the given rate and stops automatically when count hits 0. When disabled, the schedule increments at the given rate and is stopped by calling stopSchedule(). Args: enable (Bool): True if count down is enabled, False otherwise. See Also: :class:`setScheduleCount`, :class:`stopSchedule`, :class:`isCountDownEnabled` """ if enable == True: DPxEnableDinSchedCountdown() else: DPxDisableDinSchedCountdown()
[docs] @DpxExceptionDecorate def isCountDownEnabled(self): """Verifies the schedule count down mode. Returns: enable (Bool): True if the schedule is decrementing at every sample, False otherwise. See Also: :class:`setScheduleCount`, :class:`stopSchedule`, :class:`setScheduleCountDown` """ if DPxIsDinSchedCountdown() != 0: enable = True else: enable = False return enable
[docs] @DpxExceptionDecorate def startSchedule(self): """Starts a schedule. Schedules may be configured in different ways, affecting their behavior. Before a schedule is started, the user should make sure that it is properly set in the right mode. See Also: :class:`stopSchedule`, :class:`setWriteAddress`, :class:`setBaseAddress`, :class:`setScheduleOnset`, :class:`setScheduleRate`, :class:`setScheduleCountDown`, :class:`setScheduleCount` """ DPxStartDinSched()
[docs] @DpxExceptionDecorate def stopSchedule(self): """stop the active schedule for a given subsystem. Depending on how the Schedules are configured, it may not be necessary to call this method. When a schedule is using a count down, it is not required to stop the schedule. See Also: :class:`startSchedule`, :class:`setWriteAddress`, :class:`setBaseAddress`, :class:`setScheduleOnset`, :class:`setScheduleRate`, :class:`setScheduleCountDown`, :class:`setScheduleCount` """ DPxStopDinSched()
[docs] @DpxExceptionDecorate def isScheduleRunning(self): """Verifies if a schedule is currently running on the subsystem. Returns: schedule_running (Bool): True if a schedule is currently running, False otherwise. See Also: :class:`startSchedule`, :class:`stopSchedule` """ if DPxIsDinSchedRunning() == 0: schedule_running = False else: schedule_running = True return schedule_running
[docs] @DpxExceptionDecorate def setLogTimetags(self, enable): """Sets the timetag mode on the data samples. This method allows the user to enable or disable the timetag on acquired data. When enabled, each buffered sample is preceded with a 64-bit nanosecond timetag. When disabled, buffered data has no timetags. Args: enable (Bool): True to activate the timetag mode, False otherwise. See Also: :class:`isLogTimetagsEnabled` """ if enable == True: DPxEnableDinLogTimetags() else: DPxDisableDinLogTimetags()
[docs] @DpxExceptionDecorate def isLogTimetagsEnabled(self): """Verifies if the timetag mode is enabled. Returns: enable (Bool): True if timetag mode is enabled, False otherwise. See Also: :class:`setLogTimetags` """ if DPxIsDinLogTimetags() == 0: enabled = False else: enabled = True return enabled
[docs] @DpxExceptionDecorate def setLogEvents(self, enable): """Sets the transition log events mode on data samples. This method allows the user to enable or disable the transition log events on acquired data. When enabled, each transition is automatically logged. No schedule is required. This is the best way to log response buttons. When disabled, logging of transitions is done automatically. Args: enable (Bool): True to activate the log event mode, False otherwise. See Also: :class:`isLogEventsEnabled` """ if enable == True: DPxEnableDinLogEvents() else: DPxDisableDinLogEvents()
[docs] @DpxExceptionDecorate def isLogEventsEnabled(self): """Verifies if the transition log events mode is enabled. Returns: enable (Bool): True if transition log events mode is enabled, False otherwise. See Also: :class:`setLogEvents` """ if DPxIsDinLogEvents() == 0: enabled = False else: enabled = True return enabled
[docs] @DpxExceptionDecorate def setDinLog(self, buffBaseAddr = 12000000, numBuffFrames = 1000): """Configure digital input transition logging. The log reports rising and falling edges of the digital inputs, with associated timetags, and is the best way to monitor button box responses or read parallel port data. Note that the first call to StartDinLog must be preceeded by a call to SetDinLog to initialize and clear the log. Once SetDinLog has been called, StartDinLog and StopDinLog may be called multiple times to enable and disable logging. Note that logged timetags are implemented in hardware with microsecond precision. Args: bufferBaseAddress (int):Specifies the start of the RAM buffer which should hold the logged data inside the Datapixx. Use ReadDinLog to upload the logged data from this address after calling StartDinLog. numBufferFrames (int): Specifies the desired size of the log buffer in the Datapixx RAM. This buffer is circular, so it must be large enough to hold all logged transitions between successive calls to ReadDinLog. newLogFrames returned by GetDinStatus indicates the number of transitions logged since the last call to ReadDinLog. Returns: dinStatusDic (dictionary): An empty dictionary to be used with getDinLogStatus See Also: :class:`EnableDinDebounce`, :class:`StartDinLog`, :class:`StopDinLog`, :class:`GetDinStatus`, :class:`ReadDinLog` """ return DPxSetDinLog(buffBaseAddr, numBuffFrames)
[docs] @DpxExceptionDecorate def startDinLog(self): """ Starts the digital input log on the next registers update. Any transition will be recorded in this log. See Also: :class:`setDinLog`, :class:`stopDinLog` """ DPxStartDinLog()
[docs] @DpxExceptionDecorate def stopDinLog(self): """ Stops the digital input log on the next registers update. See Also: :class:`setDinLog`, :class:`stopDinLog` """ DPxDisableDinLogEvents()
[docs] @DpxExceptionDecorate def getDinLogStatus(self, dinStatusDic): """Takes a dictionary and populates it with the following digital input status information: Args: inDict (Dictionary) : * "doutDinLoopback" is 1 if digital inputs are driven internally by digital outputs, or 0 if digital inputs report real inputs from db-25 connector. * "dataDirection" is a mask showing which of the 24 bits are driving their outputs. * "dataOutStrength" is the drive strength for the ports whose outputs have been enabled by SetDinDataDirection. * "debounce" is 1 if digital inputs are debounced for 30 milliseconds. * "logRunning" is 1 if transition logging is currently active, or 0 if stopped. * "bufferBaseAddress" is the acquisition data buffer base address within the Datapixx. * "bufferSize" is the number of bytes in the acquisition data buffer. * "numBufferFrames" is the total number of samples which fit in the acquisition data buffer. * "currentWriteFrame" is the buffer frame which will be written by the next acquired sample. * "currentReadFrame" is the buffer frame which will be read by the next call to ReadDinLog. * "newLogFrames" = currentWriteFrame - currentReadFrame. This is the maximum number of frames which can be read by the next call to ReadDinLog, without causing an underflow. * "numLogUnderflows" is the number of ReadDinLog underflows which have occurred since SetDinLog. See ReadDinLog for details. See DatapixxSimonGame, DatapixxDin*Demo files for examples. See Also: :class:`startDinLog`, :class:`DinLog`, :class:`stopDinLog`, :class:`ReadDinLog` """ DPxGetDinStatus(dinStatusDic)
[docs] @DpxExceptionDecorate def readDinLog(self, frameDataDic, nReadFrames = 0): """Get the digital input log data from the internal log buffer to the local host. Args: frameDataDic (Dictionary) : * "logData" is a row vector of acquired digital input values. Each column of the vector contains an unsigned integer with the new state of digital inputs 0 to 15 after a transition. * "logTimetags" is a row vector of acquisition timetags, indicating when the corresponding transition to the state in logData occurred. The timetags are in double precision seconds since Datapixx powerup. Response times can be calculated by calling SetMarker() at stimulus onset, then subtracting GetMarker() from the logged timetags. * "underflow" is set to 1 if calls to ReadDinLog read too many frames. The newLogFrames field returned by GetDinStatus indicates the maximum number of frames which can be read by ReadDinLog. If more than this number of frames is read, an underflow occurs and there will be errors in the logged data. In addition to returning an underflow flag, the numLogUnderflows field returned by GetDinStatus will be incremented. See DatapixxSimonGame, DatapixxDin*Demo files for examples. nReadFrames (int) : The number of frames to upload, and should not exceed newLogFrames returned by GetDinStatus. If numFrames argument is missing, ReadDinLog will return all remaining logged data. Returns: DinData (list): Complete list with pairs of timestamp and values. See Also: :class:`setDinLog`, :class:`startDinLog`, :class:`stopDinLog`, :class:`getDinLogStatus` """ return DPxReadDinLog(frameDataDic, nReadFrames)