diff --git a/pycoax/coax/protocol.py b/pycoax/coax/protocol.py index de18cf8..fd6b211 100644 --- a/pycoax/coax/protocol.py +++ b/pycoax/coax/protocol.py @@ -330,6 +330,12 @@ def unpack_command_word(word): return Command(command) +def pack_data_word(byte, set_parity=True): + """Pack a data byte into a 10-bit data word.""" + parity = odd_parity(byte) if set_parity else 0 + + return (byte << 2) | (parity << 1) + def is_data_word(word): """Is data word bit set?""" return (word & 0x1) == 0 @@ -347,6 +353,10 @@ def unpack_data_word(word, check_parity=False): return byte +def pack_data_words(bytes_, set_parity=True): + """Pack data bytes into 10-bit data words.""" + return [pack_data_word(byte, set_parity=set_parity) for byte in bytes_] + def unpack_data_words(words, check_parity=False): """Unpack the data bytes from 10-bit data words.""" return bytes([unpack_data_word(word, check_parity=check_parity) for word in words]) diff --git a/pycoax/tests/test_protocol.py b/pycoax/tests/test_protocol.py index cc8575b..fdd0c37 100644 --- a/pycoax/tests/test_protocol.py +++ b/pycoax/tests/test_protocol.py @@ -4,7 +4,7 @@ from unittest.mock import Mock import context from coax import PollResponse, KeystrokePollResponse, ProtocolError -from coax.protocol import Command, Status, TerminalId, Control, SecondaryControl, pack_command_word, unpack_command_word, unpack_data_word, unpack_data_words, _execute_read_command, _execute_write_command +from coax.protocol import Command, Status, TerminalId, Control, SecondaryControl, pack_command_word, unpack_command_word, pack_data_word, unpack_data_word, pack_data_words, unpack_data_words, _execute_read_command, _execute_write_command class PollResponseTestCase(unittest.TestCase): def test_is_power_on_reset_complete(self): @@ -111,6 +111,17 @@ class UnpackCommandWordTestCase(unittest.TestCase): with self.assertRaisesRegex(ProtocolError, 'Word does not have command bit set'): unpack_command_word(0b0001000100) +class PackDataWordTestCase(unittest.TestCase): + def test(self): + self.assertEqual(pack_data_word(0x00), 0b0000000010) + self.assertEqual(pack_data_word(0x01), 0b0000000100) + self.assertEqual(pack_data_word(0xff), 0b1111111110) + + def test_disable_set_parity(self): + self.assertEqual(pack_data_word(0x00, set_parity=False), 0b0000000000) + self.assertEqual(pack_data_word(0x01, set_parity=False), 0b0000000100) + self.assertEqual(pack_data_word(0xff, set_parity=False), 0b1111111100) + class UnpackDataWordTestCase(unittest.TestCase): def test(self): self.assertEqual(unpack_data_word(0b0000000010), 0x00) @@ -124,6 +135,10 @@ class UnpackDataWordTestCase(unittest.TestCase): with self.assertRaisesRegex(ProtocolError, 'Parity error'): unpack_data_word(0b0000000000, check_parity=True) +class PackDataWordsTestCase(unittest.TestCase): + def test(self): + self.assertEqual(pack_data_words(bytes.fromhex('00 ff')), [0b0000000010, 0b1111111110]) + class UnpackDataWordsTestCase(unittest.TestCase): def test(self): self.assertEqual(unpack_data_words([0b0000000010, 0b1111111110]), bytes.fromhex('00 ff'))