diff --git a/pycoax/coax/__init__.py b/pycoax/coax/__init__.py index 56743a3..e16f132 100644 --- a/pycoax/coax/__init__.py +++ b/pycoax/coax/__init__.py @@ -7,6 +7,7 @@ from .protocol import ( PollResponse, PowerOnResetCompletePollResponse, KeystrokePollResponse, + Control, poll, poll_ack, read_status, diff --git a/pycoax/coax/protocol.py b/pycoax/coax/protocol.py index 5ed0657..4b40444 100644 --- a/pycoax/coax/protocol.py +++ b/pycoax/coax/protocol.py @@ -124,6 +124,34 @@ class TerminalId: def __repr__(self): return f'' +class Control: + """Terminal control register.""" + + def __init__(self, step_inhibit=False, display_inhibit=False, cursor_inhibit=False, + cursor_reverse=False, cursor_blink=False): + self.step_inhibit = step_inhibit + self.display_inhibit = display_inhibit + self.cursor_inhibit = cursor_inhibit + self.cursor_reverse = cursor_reverse + self.cursor_blink = cursor_blink + + @property + def value(self): + value = bool(self.step_inhibit) << 4 + value |= bool(self.display_inhibit) << 3 + value |= bool(self.cursor_inhibit) << 2 + value |= bool(self.cursor_reverse) << 1 + value |= bool(self.cursor_blink) + + return value + + def __repr__(self): + return (f', ' + f'display_inhibit={self.display_inhibit}, ' + f'cursor_inhibit={self.cursor_inhibit}, ' + f'cursor_reverse={self.cursor_reverse}, ' + f'cursor_blink={self.cursor_blink}>') + def poll(interface, action=PollAction.NONE, **kwargs): """Execute a POLL command.""" command_word = (action.value << 8) | _pack_command_word(Command.POLL) @@ -197,9 +225,11 @@ def reset(interface): """Execute a RESET command.""" raise NotImplementedError -def load_control_register(interface): +def load_control_register(interface, control, **kwargs): """Execute a LOAD_CONTROL_REGISTER command.""" - raise NotImplementedError + command_word = _pack_command_word(Command.LOAD_CONTROL_REGISTER) + + _execute_write_command(interface, command_word, bytes([control.value]), **kwargs) def load_secondary_control(interface): """Execute a LOAD_SECONDARY_CONTROL command.""" diff --git a/pycoax/examples/08_load_control_register.py b/pycoax/examples/08_load_control_register.py new file mode 100755 index 0000000..e34f313 --- /dev/null +++ b/pycoax/examples/08_load_control_register.py @@ -0,0 +1,52 @@ +#!/usr/bin/env python + +import sys +import time +from serial import Serial + +sys.path.append('..') + +from coax import Interface1, Control, poll, load_address_counter_hi, load_address_counter_lo, write_data, load_control_register + +print('Opening serial port...') + +with Serial('/dev/ttyUSB0', 115200) as serial: + print('Sleeping to allow interface time to wake up...') + + time.sleep(3) + + interface = Interface1(serial) + + print('Resetting interface...') + + version = interface.reset() + + print(f'Firmware version is {version}') + + load_address_counter_hi(interface, 0) + load_address_counter_lo(interface, 80) + write_data(interface, bytes.fromhex('a7 84 8b 8b 8e 33 00 96 8e 91 8b 83 19')) + + input('Press ENTER...') + + print('LOAD_CONTROL_REGISTER display_inhibit') + + load_control_register(interface, Control(display_inhibit=True)) + + input('Press ENTER...') + + print('LOAD_CONTROL_REGISTER cursor_inhibit') + + load_control_register(interface, Control(cursor_inhibit=True)) + + input('Press ENTER...') + + print('LOAD_CONTROL_REGISTER cursor_reverse') + + load_control_register(interface, Control(cursor_reverse=True)) + + input('Press ENTER...') + + print('LOAD_CONTROL_REGISTER cursor_blink') + + load_control_register(interface, Control(cursor_blink=True)) diff --git a/pycoax/tests/test_protocol.py b/pycoax/tests/test_protocol.py index 2b3a6ce..8a732f4 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, _execute_read_command, _execute_write_command, _pack_command_word, _unpack_command_word, _unpack_data_words, _unpack_data_word +from coax.protocol import Command, Status, TerminalId, Control, _execute_read_command, _execute_write_command, _pack_command_word, _unpack_command_word, _unpack_data_words, _unpack_data_word class PollResponseTestCase(unittest.TestCase): def test_is_power_on_reset_complete(self): @@ -63,6 +63,32 @@ class TerminalIdTestCase(unittest.TestCase): with self.assertRaisesRegex(ValueError, 'Invalid model'): terminal_id = TerminalId(0b00000000) +class ControlTestCase(unittest.TestCase): + def test_step_inhibit(self): + control = Control(step_inhibit=True) + + self.assertEqual(control.value, 0b00010000) + + def test_display_inhibit(self): + control = Control(display_inhibit=True) + + self.assertEqual(control.value, 0b00001000) + + def test_cursor_inhibit(self): + control = Control(cursor_inhibit=True) + + self.assertEqual(control.value, 0b00000100) + + def test_cursor_reverse(self): + control = Control(cursor_reverse=True) + + self.assertEqual(control.value, 0b00000010) + + def test_cursor_blink(self): + control = Control(cursor_blink=True) + + self.assertEqual(control.value, 0b00000001) + class ExecuteReadCommandTestCase(unittest.TestCase): def setUp(self): self.interface = Mock()