Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: m-labs/artiq
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: c98e08fe36fb
Choose a base ref
...
head repository: m-labs/artiq
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: e27844e0f7b5
Choose a head ref
  • 5 commits
  • 7 files changed
  • 2 contributors

Commits on Apr 19, 2015

  1. Copy the full SHA
    0c1d256 View commit details

Commits on Apr 21, 2015

  1. rpctool: import numpy

    sbourdeauducq committed Apr 21, 2015
    Copy the full SHA
    301a0e6 View commit details
  2. Copy the full SHA
    e19f889 View commit details
  3. pxi6733: add driver and controller

    fallen authored and sbourdeauducq committed Apr 21, 2015
    Copy the full SHA
    69388cc View commit details
  4. Copy the full SHA
    e27844e View commit details
2 changes: 1 addition & 1 deletion artiq/coredevice/comm_dummy.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from operator import itemgetter

from artiq.language.db import AutoDB
from artiq.language.units import ms, ns
from artiq.language.units import ms
from artiq.coredevice.runtime import LinkInterface


Empty file.
69 changes: 69 additions & 0 deletions artiq/devices/pxi6733/driver.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# Yann Sionneau <ys@m-labs.hk>, 2015

from ctypes import byref


class DAQmxSim:
def load_sample_values(self, values):
pass

def close(self):
pass


def done_callback_py(taskhandle, status, callback_data):
callback_data.daq.DAQmxClearTask(taskhandle)
callback_data.tasks.remove(taskhandle)


class DAQmx:
"""NI PXI6733 DAQ interface."""

def __init__(self, device, analog_output, clock):
import PyDAQmx as daq

self.device = device
self.analog_output = analog_output
self.clock = clock
self.tasks = []
self.daq = daq

def load_sample_values(self, values):
"""Load sample values into PXI 6733 device.
This loads sample values into the PXI 6733 device and then
configures a task to output those samples at each clock rising
edge.
A callback is registered to clear the task (unallocate resources)
when the task has completed.
:param values: A numpy array of sample values to load in the device.
"""

t = self.daq.Task()
t.CreateAOVoltageChan(self.device+b"/"+self.analog_output, b"",
min(values), max(values),
self.daq.DAQmx_Val_Volts, None)
t.CfgSampClkTiming(self.clock, 1000.0, self.daq.DAQmx_Val_Rising,
self.daq.DAQmx_Val_FiniteSamps, len(values))
num_samps_written = self.daq.int32()
ret = t.WriteAnalogF64(len(values), False, 0,
self.daq.DAQmx_Val_GroupByChannel, values,
byref(num_samps_written), None)
if num_samps_written.value != len(values):
raise Exception("Error: only {} sample values were written"
.format(num_samps_written.value))
if ret:
raise Exception("Error while writing samples to channel's buffer")

done_callback = self.daq.DAQmxDoneEventCallbackPtr(done_callback_py)
self.tasks.append(t.taskHandle)
self.daq.DAQmxRegisterDoneEvent(t.taskHandle, 0, done_callback, self)
t.StartTask()

def close(self):
"""Clear all pending tasks."""

for t in self.tasks:
self.daq.DAQmxClearTask(t)
1 change: 1 addition & 0 deletions artiq/frontend/artiq_rpctool.py
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import argparse
import textwrap
import sys
import numpy as np # Needed to use numpy in RPC call arguments on cmd line

from artiq.protocols.pc_rpc import Client

43 changes: 43 additions & 0 deletions artiq/frontend/pxi6733_controller.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/usr/bin/env python3
# Yann Sionneau <ys@m-labs.hk>, 2015

import argparse

from artiq.protocols.pc_rpc import simple_server_loop
from artiq.devices.pxi6733.driver import DAQmx, DAQmxSim
from artiq.tools import verbosity_args, init_logger, simple_network_args


def get_argparser():
parser = argparse.ArgumentParser(description="NI PXI 6733 controller")
simple_network_args(parser, 3256)
parser.add_argument("-d", "--device", default=None,
help="Device name (e.g. Dev1)."
" Omit for simulation mode.")
parser.add_argument("-c", "--clock", default="PFI5",
help="Input clock pin name (default: PFI5)")
parser.add_argument("-a", "--analog-output", default="ao0",
help="Analog output pin name (default: ao0)")
verbosity_args(parser)
return parser


def main():
args = get_argparser().parse_args()
init_logger(args)

if args.device is None:
daq = DAQmxSim()
else:
daq = DAQmx(bytes(args.device, "ascii"),
bytes(args.analog_output, "ascii"),
bytes(args.clock, "ascii"))

try:
simple_server_loop({"pxi6733": daq},
args.bind, args.port)
finally:
daq.close()

if __name__ == "__main__":
main()
41 changes: 41 additions & 0 deletions artiq/test/pxi6733.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import unittest
import os
import numpy as np

from artiq.devices.pxi6733.driver import DAQmxSim, DAQmx


pxi6733_device = os.getenv("PXI6733_DEVICE")
pxi6733_analog_output = os.getenv("PXI6733_ANALOG_OUTPUT")
pxi6733_clock = os.getenv("PXI6733_CLOCK")


class GenericPXI6733Test:
def test_load_sample_values(self):
test_vector = np.array([1.0, 2.0, 3.0, 4.0], dtype=float)
self.cont.load_sample_values(test_vector)

def test_close_1(self):
self.cont.close()

def test_close_2(self):
test_vector = np.array([1.0, 2.0, 3.0, 4.0], dtype=float)
self.cont.load_sample_values(test_vector)
self.cont.close()


@unittest.skipUnless(pxi6733_device, "no hardware")
class TestPXI6733(GenericPXI6733Test, unittest.TestCase):
def setUp(self):
args = dict()
args["device"] = bytes(pxi6733_device, "ascii")
args["analog_output"] = bytes(pxi6733_analog_output, "ascii") \
if pxi6733_analog_output else b"ao0"
args["clock"] = bytes(pxi6733_clock, "ascii") \
if pxi6733_clock else b"PFI5"
self.cont = DAQmx(**args)


class TestPXI6733Sim(GenericPXI6733Test, unittest.TestCase):
def setUp(self):
self.cont = DAQmxSim()
5 changes: 3 additions & 2 deletions doc/manual/utilities.rst
Original file line number Diff line number Diff line change
@@ -61,10 +61,11 @@ in order to call remote functions of an ARTIQ controller.
$ artiq_rpctool.py hostname port call -t target f x1 x2 ... xN

You can use Python syntax to compute arguments as they will be passed
to the ``eval()`` primitive. But beware to use quotes to separate
arguments which use spaces::
to the ``eval()`` primitive. The numpy package is available in the namespace
as ``np``. Beware to use quotes to separate arguments which use spaces::

$ artiq_rpctool.py hostname port call -t target f '3 * 4 + 2' True '[1, 2]'
$ artiq_rpctool.py ::1 3256 call load_sample_values 'np.array([1.0, 2.0], dtype=float)'

If the called function has a return value, it will get printed to
the standard output if the value is not None like in the standard