1 # Copyright (C) 2011-2012 W. Trevor King <wking@tremily.us>
3 # This file is part of pycomedi.
5 # pycomedi is free software: you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation, either version 2 of the License, or (at your option) any later
10 # pycomedi is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
14 # You should have received a copy of the GNU General Public License along with
15 # pycomedi. If not, see <http://www.gnu.org/licenses/>.
17 "Wrap Comedi's `comedi_insn` struct in the `Insn` class"
19 cimport libc.stdlib as _stdlib
20 import numpy as _numpy
22 from pycomedi cimport _comedi_h
23 from pycomedi cimport _comedilib_h
24 from . import PyComediError as _PyComediError
25 from . import chanspec as _chanspec
26 from . import constant as _constant
29 cdef class Insn (object):
30 """A Comedi instruction
32 >>> from .constant import INSN, AREF
38 chanspec: <ChanSpec chan:0 range:0 aref:ground flags:->
39 >>> i.insn = INSN.write
41 `data` takes any iterable that supports `length()` and returns NumPy arrays.
43 >>> i.data = [1, 2, 3]
45 <type 'numpy.ndarray'>
47 `subdev` is currently just an integer (not a `Subdevice` instance).
55 Because `ChanSpec` instances store their value internally (not
56 using the value stored in the `Insn` instance), direct operations
57 on them have no effect on the intruction.
59 >>> i.chanspec.aref = AREF.diff
61 <ChanSpec chan:0 range:0 aref:ground flags:->
63 To have an effect, you need to explicity set the `chanspec` attribute:
66 >>> c.aref = AREF.diff
69 <ChanSpec chan:0 range:0 aref:diff flags:->
75 chanspec: <ChanSpec chan:0 range:0 aref:diff flags:->
78 self._insn.insn = _constant.INSN.read.value
79 self._insn.data = NULL
80 self._fields = ['insn', 'data', 'subdev', 'chanspec']
82 def __dealloc__(self):
83 if self._insn.data is not NULL:
84 _stdlib.free(self._insn.data)
86 cdef _comedi_h.comedi_insn get_comedi_insn(self):
90 max_field_length = max([len(f) for f in self._fields])
92 for f in self._fields:
93 lines.append('%*s: %s' % (max_field_length, f, getattr(self, f)))
94 return '\n'.join(lines)
97 return _constant.INSN.index_by_value(self._insn.insn)
98 def _insn_set(self, value):
99 self._insn.insn = _constant.bitwise_value(value)
100 insn = property(fget=_insn_get, fset=_insn_set)
103 data = _numpy.ndarray(shape=(self._insn.n,), dtype=_numpy.uint)
104 # TODO: point into existing data array?
105 for i in range(self._insn.n):
106 data[i] = self._insn.data[i]
108 def _data_set(self, value):
109 if self._insn.data is not NULL:
110 _stdlib.free(self._insn.data)
111 self._insn.n = len(value)
112 self._insn.data = <_comedi_h.lsampl_t *>_stdlib.malloc(
113 self._insn.n*sizeof(_comedi_h.lsampl_t))
114 if self._insn.data is NULL:
116 raise _PyComediError('out of memory?')
117 for i,x in enumerate(value):
118 self._insn.data[i] = x
119 data = property(fget=_data_get, fset=_data_set)
121 def _subdev_get(self):
122 return int(self._insn.subdev)
123 def _subdev_set(self, value):
124 self._insn.subdev = value
125 subdev = property(fget=_subdev_get, fset=_subdev_set)
127 def _chanspec_get(self):
128 c = _chanspec.ChanSpec()
129 c.value = self._insn.chanspec
131 def _chanspec_set(self, value):
132 self._insn.chanspec = _constant.bitwise_value(value)
133 chanspec = property(fget=_chanspec_get, fset=_chanspec_set)