Mask range.unit with 0xff when determining the unit.
[pycomedi.git] / pycomedi / range.pyx
1 # Copyright (C) 2011-2012 W. Trevor King <wking@drexel.edu>
2 #
3 # This file is part of pycomedi.
4 #
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
8 # version.
9 #
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.
13 #
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/>.
16
17 "Wrap `comedi_range` in a Python class"
18
19 from constant cimport BitwiseOperator as _BitwiseOperator
20 import constant as _constant
21
22
23 cdef class Range (_BitwiseOperator):
24     """Stucture displaying a possible channel range
25
26     Warning: You probably want to use `channel.Channel.get_range()` or
27     `channel.Channel.find_range()` rather than initializing this
28     stucture by hand.  If you do initialize it by hand (or set any
29     values by hand), remember that it may no longer correspond to your
30     devices built-in range with that index.
31
32     For consistency with other integer wrappers, the range index is
33     stored in the `.value` attribute.
34
35     >>> from constant import UNIT
36     >>> r = Range(1)
37     >>> r
38     <Range unit:volt min:0.0 max:0.0>
39     >>> r.value
40     1
41     >>> r.unit = UNIT.mA
42     >>> r.min = -2.71828
43     >>> r.max = 3.14159
44     >>> r
45     <Range unit:mA min:-2.71828 max:3.14159>
46     >>> r.unit
47     <_NamedInt mA>
48     """
49     # other data gets packed into the unit unsigned int (e.g RF_EXTERNAL)
50     _uint_all = 0xffffffffL
51     _unit_all = 0xff
52
53     def __cinit__(self):
54         self.value = -1
55
56     def __init__(self, value):
57         self.range.unit = 0
58         self.range.min = 0
59         self.range.max = 0
60         self.value = value
61
62     cdef set_comedi_range(self, _comedilib_h.comedi_range range):
63         self.range = range
64
65     def __str__(self):
66         fields = ['%s:%s' % (f, getattr(self, f))
67                   for f in ['unit', 'min', 'max']]
68         return '<%s %s>' % (self.__class__.__name__, ' '.join(fields))
69
70     def __repr__(self):
71         return self.__str__()
72
73     def _unit_get(self):
74         return _constant.UNIT.index_by_value(self.range.unit & self._unit_all)
75     def _unit_set(self, value):
76         self.range.unit &= self._uint_all - self._unit_all
77         self.range.unit |= _constant.bitwise_value(value) & self._unit_all
78     unit = property(fget=_unit_get, fset=_unit_set)
79
80     def _min_get(self):
81         return self.range.min
82     def _min_set(self, value):
83         self.range.min = value
84     min = property(fget=_min_get, fset=_min_set)
85
86     def _max_get(self):
87         return self.range.max
88     def _max_set(self, value):
89         self.range.max = value
90     max = property(fget=_max_get, fset=_max_set)