diff options
author | cliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a> | 2004-04-16 01:10:29 +0000 |
---|---|---|
committer | cliechti <cliechti@f19166aa-fa4f-0410-85c2-fa1106f25c8a> | 2004-04-16 01:10:29 +0000 |
commit | b10558075a38cc99d4463c699cd4fb73aa94eae7 (patch) | |
tree | 82ed2c1bb5f7ec1d91519d72e3f8db2b83394e5a /pyparallel/parallel/parallelutil.py | |
parent | c6178260b0154cee256732353dc988e9464d50be (diff) | |
download | pyserial-git-b10558075a38cc99d4463c699cd4fb73aa94eae7.tar.gz |
- bit access over properties to a prallel port instance
- VirtualParallelPort for testing and simulation
- unittests
Diffstat (limited to 'pyparallel/parallel/parallelutil.py')
-rw-r--r-- | pyparallel/parallel/parallelutil.py | 124 |
1 files changed, 124 insertions, 0 deletions
diff --git a/pyparallel/parallel/parallelutil.py b/pyparallel/parallel/parallelutil.py new file mode 100644 index 0000000..a1a262a --- /dev/null +++ b/pyparallel/parallel/parallelutil.py @@ -0,0 +1,124 @@ +class BitaccessMeta(type): + """meta class that adds bit access properties to a + parallel port implementation""" + + def __new__(self, classname, bases, classdict): + klass = type.__new__(self, classname, bases, classdict) + #status lines + klass.paperOut = property(klass.getInPaperOut, None, "Read the PaperOut signal") + #control lines + klass.dataStrobe = property(None, klass.setDataStrobe, "Set the DataStrobe signal") + #XXX ... other bits + #data bits + for bit in range(8): + mask = (1<<bit) + def getter(self, mask=mask): + return (self.getData() & mask) != 0 + def setter(self, b, mask=mask): + if b: + self.setData(self.getData() | mask) + else: + self.setData(self.getData() & ~mask) + setattr(klass, "D%d" % bit, property(getter, setter, "Access databit %d" % bit)) + #nibbles + for name, shift, width in [('D0_D3', 0, 4), ('D4_D7', 4, 4)]: + mask = (1<<width) - 1 + def getter(self, shift=shift, mask=mask): + return (self.getData() >> shift) & mask + def setter(self, b, shift=shift, mask=mask): + self.setData((self.getData() & ~(mask<<shift)) | ((b&mask) << shift)) + setattr(klass, name, property(getter, setter, "Access to %s" % name)) + return klass + +class VirtualParallelPort: + """provides a virtual parallel port implementation, useful + for tests and simulations without real hardware""" + + __metaclass__ = BitaccessMeta + + def __init__(self, port=None): + self._data = 0 + + def setData(self, value): + self._data = value + + def getData(self): + return self._data + + #inputs return dummy value + def getInPaperOut(self): return self._dummy + #... + #outputs just store a tuple with (action, value) pair + def setDataStrobe(self, value): self._last = ('setDataStrobe', value) + #... + +#testing +if __name__ == '__main__': + import unittest, sys + + class TestBitaccess(unittest.TestCase): + """Tests a port with no timeout""" + def setUp(self): + self.p = VirtualParallelPort() + + def testDatabits(self): + """bit by bit D0..D7""" + p = self.p + p.D0 = p.D2 = p.D4 = p.D6 = 1 + self.failUnlessEqual(p._data, 0x55) + self.failUnlessEqual( + [p.D7, p.D6, p.D5, p.D4, p.D3, p.D2, p.D1, p.D0], + [0, 1, 0, 1, 0, 1, 0, 1] + ) + p._data <<= 1 + self.failUnlessEqual( + [p.D7, p.D6, p.D5, p.D4, p.D3, p.D2, p.D1, p.D0], + [1, 0, 1, 0, 1, 0, 1, 0] + ) + + def testDatabitsGroups(self): + """nibbles D0..D7""" + p = self.p + p.D0_D3 = 14 + self.failUnlessEqual(p._data, 0x0e) + p.D0_D3 = 0 + p.D4_D7 = 13 + self.failUnlessEqual(p._data, 0xd0) + p.D0_D3 = p.D4_D7 = 0xa + self.failUnlessEqual(p._data, 0xaa) + #test bit patterns + for x in range(256): + #test getting + p._data = x + self.failUnlessEqual((p.D4_D7, p.D0_D3), (((x>>4) & 0xf), (x & 0xf))) + #test setting + p._data = 0 + (p.D4_D7, p.D0_D3) = (((x>>4) & 0xf), (x & 0xf)) + self.failUnlessEqual(p._data, x) + + def testStatusbits(self): + """bit by bit status lines""" + #read the property: + self.p._dummy = 0 + self.failUnlessEqual(self.p.paperOut, 0) + + self.p._dummy = 1 + self.failUnlessEqual(self.p.paperOut, 1) + + #read only, must not be writable: + self.failUnlessRaises(AttributeError, setattr, self.p, 'paperOut', 1) + + def testControlbits(self): + """bit by bit control lines""" + self.p.dataStrobe = 0 + self.failUnlessEqual(self.p._last, ('setDataStrobe', 0)) + self.p.dataStrobe = 1 + self.failUnlessEqual(self.p._last, ('setDataStrobe', 1)) + + #write only, must not be writable: + self.failUnlessRaises(AttributeError, getattr, self.p, 'dataStrobe') + + sys.argv.append('-v') + # When this module is executed from the command-line, it runs all its tests + unittest.main() +
\ No newline at end of file |