4c8a401b55656072cba88880dcf8a036a37483ce
[pyafm.git] / pyafm / digital_port.py
1 # Copyright
2
3 from pycomedi.channel import DigitalChannel as _DigitalChannel
4 import pypiezo.base as _base
5
6
7 class DigitalPort (object):
8     """A digital input/output port (i.e. cluster of channels).
9
10     >>> from pyafm.config import DigitalPortConfig
11
12     >>> devices = []
13
14     >>> config = DigitalPortConfig()
15     >>> config['channels'] = [1, 2, 3, 4]
16     >>> config['name'] = 'test port'
17
18     >>> port = DigitalPort(config=config, devices=devices)
19     >>> port.write_bitfield(13)
20     >>> port.write([1, 0, 1, 0])
21     >>> port.write_bitfield(0)
22
23     >>> for device in devices:
24     ...     device.close()
25     """
26     def __init__(self, config, devices=None):
27         self.config = config
28         self.subdevice = None
29         self.load_from_config(devices=devices)
30
31     def load_from_config(self, devices):
32         c = self.config  # reduce verbosity
33         if self.subdevice is None:
34             device = _base.load_device(filename=c['device'], devices=devices)
35             if c['subdevice'] < 0:
36                 self.subdevice = device.find_subdevice_by_type(
37                     c['subdevice-type'])
38             else:
39                 self.subdevice = device.subdevice(index=c['subdevice'])
40             self.channels = []
41             self.write_mask = 0
42             for index in c['channels']:
43                 channel = self.subdevice.channel(
44                     index=index, factory=_DigitalChannel)
45                 channel.dio_config(c['direction'])
46                 self.write_mask |= 1 << index
47                 self.channels.append(channel)
48         self.name = c['name']
49
50     def setup_config(self):
51         self.config['device'] = self.subdevice.device.filename
52         self.config['subdevice'] = self.subdevice.index
53         self.config['channels'] = [c.index for c in self.channels]
54         if self.channels:
55             self.config['direction'] = self.channels[0].dio_get_config()
56
57     def write(self, values):
58         value = 0
59         for channel,val in zip(self.channels, values):
60             value &= val * (1 << channel.index)
61         self.write_bitfield(value)
62
63     def write_bitfield(self, value):
64         self.subdevice.dio_bitfield(bits=value, write_mask=self.write_mask)