u2xbar 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
u2xbar-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mete Balci
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
u2xbar-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,235 @@
1
+ Metadata-Version: 2.4
2
+ Name: u2xbar
3
+ Version: 0.1.0
4
+ Summary: Control tool and library for the u2xbar USB crossbar
5
+ Author: Mete Balci
6
+ License-Expression: MIT
7
+ Project-URL: Repository, https://github.com/metebalci/u2xbar-sw
8
+ Classifier: Development Status :: 2 - Pre-Alpha
9
+ Classifier: Environment :: Console
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Topic :: System :: Hardware :: Universal Serial Bus (USB)
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: pyserial>=3.5
18
+ Dynamic: license-file
19
+
20
+ # u2xbar
21
+
22
+ Control tool and Python library for u2xbar, a USB 2.0 crossbar that connects
23
+ USB devices to computers under program control. The tool speaks the unit's
24
+ control protocol (`docs/protocol.md` in the u2xbar-sw repository) on its
25
+ control port, a USB CDC ACM serial port.
26
+
27
+ ## Terms
28
+
29
+ - A host port is where a computer connects.
30
+ - A device port is where a peripheral connects.
31
+ - A hub port is a downstream port of one of the unit's internal hubs. Hub
32
+ port p leads to device port p.
33
+ - A connection is a device port assigned to a host port.
34
+ - The control port is the unit's own USB port for the control protocol.
35
+
36
+ ## Install
37
+
38
+ ```
39
+ pip install u2xbar
40
+ ```
41
+
42
+ It needs Python 3.10 or later and pyserial. On Linux, the user needs access to
43
+ the control port (usually the group `dialout`).
44
+
45
+ ## Finding a unit
46
+
47
+ The tool looks for a serial port with USB ID 16C0:27DD whose serial number
48
+ starts with `u2xbar.metebalci.com:`. The part after the colon is the unit's
49
+ unique ID. With several units, `--serial <unique ID>` chooses one. `--port
50
+ <path>` uses that port and skips the search; it also works on the firmware's
51
+ debug console.
52
+
53
+ ## Command line
54
+
55
+ The commands follow the protocol:
56
+
57
+ ```
58
+ u2xbar version
59
+ u2xbar list
60
+ u2xbar connect 3 2 # device port 3 to host port 2
61
+ u2xbar disconnect 3 # or: disconnect all
62
+ u2xbar dev 3 vbus off # dev <d> vbus|data on|off, dev <d> host <h>|none
63
+ u2xbar host 1 detach # host <h> vbus|data on|off, attach, detach
64
+ u2xbar hub 1 boost 0,2,2,2,2 # or: hub <h> boost <p>|up|all <0-3>, reset, regs
65
+ u2xbar param discharge_ms 30
66
+ u2xbar events on
67
+ u2xbar reset
68
+ u2xbar dfu # sends the command only; see "Firmware update"
69
+ ```
70
+
71
+ The tool adds:
72
+
73
+ - `status [--watch] [--interval S] [--count N]` reads the whole state.
74
+ - `measure [--interval S] [--count N] [--csv]` reads the sensors; the CSV has
75
+ a time column in UTC.
76
+ - `raw <line>` sends one protocol line and prints the reply.
77
+ - `shell` sends the lines you type and prints replies and events.
78
+ - `run <script>` runs a file of protocol lines (or `-` for stdin). `#` starts
79
+ a comment, and `sleep <seconds>` waits on the computer. The whole script is
80
+ checked before the first line is sent. The run stops at the first `err`
81
+ unless `--keep-going` is given.
82
+ - `topo` (Linux) shows where each host port's hub and the device on each
83
+ device port sit in this computer's USB tree: bus path, VID:PID, speed and
84
+ product. It finds the hubs by their serial number `<unique ID>-H<h>`.
85
+
86
+ `--json` prints records as JSON, one document per line. Events go to stderr,
87
+ except in `shell` and `run`.
88
+
89
+ Exit codes: 0 ok, 1 the unit answered `err` or a test failed, 2 usage error,
90
+ 3 no unit, an I/O error (the port, a timeout, or a reply that breaks the
91
+ protocol), or a test that cannot start.
92
+
93
+ ## Firmware update
94
+
95
+ ```
96
+ u2xbar dfu --image u2xbar.bin [--dfu-util PATH] [--wait S]
97
+ ```
98
+
99
+ The tool reads the unit's `version`, sends `dfu`, and waits for the STM32
100
+ system bootloader (USB 0483:DF11) to appear in sysfs (Linux). It then runs
101
+
102
+ ```
103
+ dfu-util -d 0483:df11 -p <bus path> -a 0 -s 0x08000000:leave -D u2xbar.bin
104
+ ```
105
+
106
+ with the bus path of the bootloader that appeared, so another board in DFU
107
+ mode is left alone. When dfu-util is done, the tool waits for the unit to come
108
+ back on its control port (found by its unique ID, or at `--port`) and prints
109
+ its `version`. dfu-util is a separate program; the tool checks that it exists
110
+ before it sends `dfu`. `--wait` (10 s) bounds each of the two waits.
111
+
112
+ ## Acceptance tests
113
+
114
+ The tests check a unit on this computer (Linux). Each host port to be tested
115
+ must be connected to this computer, so that `topo` finds its hub.
116
+
117
+ ```
118
+ u2xbar test enum [--hosts H,...] [--devices D,...] [--timeout S]
119
+ [--allow-full-speed D,...] [--no-kernel-log]
120
+ u2xbar test moves --count N --seed S [--hosts H,...] [--devices D,...] [--timeout S]
121
+ u2xbar test read --device /dev/sdX --size GB [--baseline MB/s] [--margin PERCENT] [--force]
122
+ ```
123
+
124
+ `test enum` and `test moves` start with a first pass: every selected device
125
+ port is connected to the first selected host port, and the device that
126
+ appears on each hub port is recorded. A device is known by its VID:PID and
127
+ serial number, or, without a serial number, by its VID:PID and hub port. A
128
+ device port whose device does not enumerate (`ufp=1` and no USB device) is
129
+ reported.
130
+
131
+ - `test enum` connects each device to each selected host port, one at a
132
+ time. Each step passes if the device appears on that host port's hub at its
133
+ hub port within `--timeout` (5 s), at 480M (or 12M on the device ports
134
+ named in `--allow-full-speed`), on no other hub, is gone after the
135
+ disconnect, and the kernel log has no new USB error (priority err or worse
136
+ from `usb`, `hub` or a host controller driver). The kernel log is read from
137
+ `/dev/kmsg` or, without the right to read it, from `journalctl -k`;
138
+ `--no-kernel-log` skips the check. The tool prints a table and the
139
+ failures.
140
+ - `test moves` makes N random moves (`connect d h` to another host port) of
141
+ the device ports that have devices. After each move the same device must
142
+ appear on the new host port within `--timeout` and on no other host port.
143
+ The moves depend only on the seed and the ports, so a run can be repeated.
144
+ The tool prints each move, a summary (moves, failures, retries, the slowest
145
+ arrival) and every failure. A failed step or move does not stop either
146
+ test; the exit code is 1 at the end.
147
+ - `test read` reads the first `--size` GB (10^9 bytes) of a block device in
148
+ 4 MiB reads, with `O_DIRECT` where the file system allows it and otherwise
149
+ with the page cache dropped through `posix_fadvise`, and prints the rate in
150
+ MB/s (10^6 bytes per second). With `--baseline`, the rate measured through
151
+ a direct cable, it passes if it is at most `--margin` (3 %) slower. It only
152
+ reads, and it refuses a device that is mounted (or one of its partitions)
153
+ unless `--force` is given. It needs no unit.
154
+
155
+ A full-speed device that comes up as low speed or not at all gets one retry
156
+ (disconnect and connect again), which is counted and reported: the USB2517
157
+ can detect a full-speed device as low speed when the port reset comes early
158
+ in a frame (errata DS80000628A, Module 4). In `test enum` this holds for the
159
+ device ports in `--allow-full-speed`.
160
+
161
+ `--timeout` of a test is the time a device may take to appear or go; the
162
+ time per protocol command is set with `--timeout` before the word `test`.
163
+ `--poll` (0.05 s) is the time between scans of the USB tree.
164
+
165
+ ## Library
166
+
167
+ ```python
168
+ from u2xbar import Unit
169
+
170
+ with Unit() as unit: # or Unit(serial="..."), Unit(port="/dev/ttyACM0")
171
+ print(unit.version())
172
+ unit.connect(3, 2)
173
+ for port in unit.list():
174
+ print(port.port, port.host, port.vbus, port.data)
175
+ print(unit.measure().i5_ma)
176
+ ```
177
+
178
+ Each protocol command has a method, and `command(line)` sends any line.
179
+ Results are dataclasses; a value the unit gives as `-` is `None`. An `err`
180
+ reply raises `UnitError`, which carries the code. Events go to the
181
+ `on_event` callback, or wait for `poll_events()`.
182
+
183
+ ## Tests
184
+
185
+ ```
186
+ uv venv <venv>
187
+ VIRTUAL_ENV=<venv> uv pip install -e . --group test
188
+ <venv>/bin/python -m pytest
189
+ ```
190
+
191
+ The tests run the tool against a fake unit on a pseudo-terminal and need no
192
+ hardware. For the acceptance tests, a fake world ties the fake unit's
193
+ connection commands to a fake sysfs tree, with devices that are slow, come up
194
+ as low speed, appear on the wrong hub, stay behind, or never appear; a fake
195
+ kernel log, a file as the block device, and a fake dfu-util complete it. One
196
+ test reads this computer's kernel log and sysfs; it runs only with
197
+ `U2XBAR_REAL_SYSTEM=1`.
198
+
199
+ ### Integration tests
200
+
201
+ The integration tests (`tests/test_sim_integration.py`) run the tool against
202
+ the firmware simulator `u2xbar-sim` (`sim/` in the u2xbar-sw repository): the
203
+ firmware's core and protocol on the board model of its PC tests, served on a
204
+ pseudo-terminal in real time. They run only when `U2XBAR_SIM` names the
205
+ simulator binary:
206
+
207
+ ```
208
+ cmake -S ../sim -B <build> -G Ninja
209
+ cmake --build <build>
210
+ U2XBAR_SIM=<build>/u2xbar-sim <venv>/bin/python -m pytest tests/test_sim_integration.py
211
+ ```
212
+
213
+ Each test starts its own simulator, with its pty file in the test's
214
+ temporary directory, and stops it at the end, also when the test fails. A
215
+ test drives the simulated unit through the command line (`python -m u2xbar
216
+ --port <pty>`, one process per command) or through `Unit`; most tests run
217
+ both ways. The simulator's `state` query checks the simulated hardware: for
218
+ example, that a connected device port's switch selects the hub of its host
219
+ port and that its VBUS is on, or that the discharge FET comes on only after
220
+ VBUS went off. Injections change the simulated world: a device attached, a
221
+ fault that lasts past `fault_off_ms`, a computer that removes VBUS, the 5 V
222
+ rail, a chip that does not answer. The tests cover every command, the
223
+ parameters and their bounds, the error codes `syntax`, `range`, `state` and
224
+ `hw` (the simulator cannot make an I2C transfer time out), events, `run`,
225
+ `raw`, `shell`, `measure --csv`, `--json` and the exit codes. A hardware-rule
226
+ violation of the board model fails the test.
227
+
228
+ `scripts/check.sh` in the repository builds the simulator and runs these
229
+ tests with the other checks.
230
+
231
+ ## How it was written
232
+
233
+ The code and documentation are written with
234
+ [Claude Code](https://claude.com/claude-code), using Anthropic's Claude Opus
235
+ 5.5 model.
u2xbar-0.1.0/README.md ADDED
@@ -0,0 +1,216 @@
1
+ # u2xbar
2
+
3
+ Control tool and Python library for u2xbar, a USB 2.0 crossbar that connects
4
+ USB devices to computers under program control. The tool speaks the unit's
5
+ control protocol (`docs/protocol.md` in the u2xbar-sw repository) on its
6
+ control port, a USB CDC ACM serial port.
7
+
8
+ ## Terms
9
+
10
+ - A host port is where a computer connects.
11
+ - A device port is where a peripheral connects.
12
+ - A hub port is a downstream port of one of the unit's internal hubs. Hub
13
+ port p leads to device port p.
14
+ - A connection is a device port assigned to a host port.
15
+ - The control port is the unit's own USB port for the control protocol.
16
+
17
+ ## Install
18
+
19
+ ```
20
+ pip install u2xbar
21
+ ```
22
+
23
+ It needs Python 3.10 or later and pyserial. On Linux, the user needs access to
24
+ the control port (usually the group `dialout`).
25
+
26
+ ## Finding a unit
27
+
28
+ The tool looks for a serial port with USB ID 16C0:27DD whose serial number
29
+ starts with `u2xbar.metebalci.com:`. The part after the colon is the unit's
30
+ unique ID. With several units, `--serial <unique ID>` chooses one. `--port
31
+ <path>` uses that port and skips the search; it also works on the firmware's
32
+ debug console.
33
+
34
+ ## Command line
35
+
36
+ The commands follow the protocol:
37
+
38
+ ```
39
+ u2xbar version
40
+ u2xbar list
41
+ u2xbar connect 3 2 # device port 3 to host port 2
42
+ u2xbar disconnect 3 # or: disconnect all
43
+ u2xbar dev 3 vbus off # dev <d> vbus|data on|off, dev <d> host <h>|none
44
+ u2xbar host 1 detach # host <h> vbus|data on|off, attach, detach
45
+ u2xbar hub 1 boost 0,2,2,2,2 # or: hub <h> boost <p>|up|all <0-3>, reset, regs
46
+ u2xbar param discharge_ms 30
47
+ u2xbar events on
48
+ u2xbar reset
49
+ u2xbar dfu # sends the command only; see "Firmware update"
50
+ ```
51
+
52
+ The tool adds:
53
+
54
+ - `status [--watch] [--interval S] [--count N]` reads the whole state.
55
+ - `measure [--interval S] [--count N] [--csv]` reads the sensors; the CSV has
56
+ a time column in UTC.
57
+ - `raw <line>` sends one protocol line and prints the reply.
58
+ - `shell` sends the lines you type and prints replies and events.
59
+ - `run <script>` runs a file of protocol lines (or `-` for stdin). `#` starts
60
+ a comment, and `sleep <seconds>` waits on the computer. The whole script is
61
+ checked before the first line is sent. The run stops at the first `err`
62
+ unless `--keep-going` is given.
63
+ - `topo` (Linux) shows where each host port's hub and the device on each
64
+ device port sit in this computer's USB tree: bus path, VID:PID, speed and
65
+ product. It finds the hubs by their serial number `<unique ID>-H<h>`.
66
+
67
+ `--json` prints records as JSON, one document per line. Events go to stderr,
68
+ except in `shell` and `run`.
69
+
70
+ Exit codes: 0 ok, 1 the unit answered `err` or a test failed, 2 usage error,
71
+ 3 no unit, an I/O error (the port, a timeout, or a reply that breaks the
72
+ protocol), or a test that cannot start.
73
+
74
+ ## Firmware update
75
+
76
+ ```
77
+ u2xbar dfu --image u2xbar.bin [--dfu-util PATH] [--wait S]
78
+ ```
79
+
80
+ The tool reads the unit's `version`, sends `dfu`, and waits for the STM32
81
+ system bootloader (USB 0483:DF11) to appear in sysfs (Linux). It then runs
82
+
83
+ ```
84
+ dfu-util -d 0483:df11 -p <bus path> -a 0 -s 0x08000000:leave -D u2xbar.bin
85
+ ```
86
+
87
+ with the bus path of the bootloader that appeared, so another board in DFU
88
+ mode is left alone. When dfu-util is done, the tool waits for the unit to come
89
+ back on its control port (found by its unique ID, or at `--port`) and prints
90
+ its `version`. dfu-util is a separate program; the tool checks that it exists
91
+ before it sends `dfu`. `--wait` (10 s) bounds each of the two waits.
92
+
93
+ ## Acceptance tests
94
+
95
+ The tests check a unit on this computer (Linux). Each host port to be tested
96
+ must be connected to this computer, so that `topo` finds its hub.
97
+
98
+ ```
99
+ u2xbar test enum [--hosts H,...] [--devices D,...] [--timeout S]
100
+ [--allow-full-speed D,...] [--no-kernel-log]
101
+ u2xbar test moves --count N --seed S [--hosts H,...] [--devices D,...] [--timeout S]
102
+ u2xbar test read --device /dev/sdX --size GB [--baseline MB/s] [--margin PERCENT] [--force]
103
+ ```
104
+
105
+ `test enum` and `test moves` start with a first pass: every selected device
106
+ port is connected to the first selected host port, and the device that
107
+ appears on each hub port is recorded. A device is known by its VID:PID and
108
+ serial number, or, without a serial number, by its VID:PID and hub port. A
109
+ device port whose device does not enumerate (`ufp=1` and no USB device) is
110
+ reported.
111
+
112
+ - `test enum` connects each device to each selected host port, one at a
113
+ time. Each step passes if the device appears on that host port's hub at its
114
+ hub port within `--timeout` (5 s), at 480M (or 12M on the device ports
115
+ named in `--allow-full-speed`), on no other hub, is gone after the
116
+ disconnect, and the kernel log has no new USB error (priority err or worse
117
+ from `usb`, `hub` or a host controller driver). The kernel log is read from
118
+ `/dev/kmsg` or, without the right to read it, from `journalctl -k`;
119
+ `--no-kernel-log` skips the check. The tool prints a table and the
120
+ failures.
121
+ - `test moves` makes N random moves (`connect d h` to another host port) of
122
+ the device ports that have devices. After each move the same device must
123
+ appear on the new host port within `--timeout` and on no other host port.
124
+ The moves depend only on the seed and the ports, so a run can be repeated.
125
+ The tool prints each move, a summary (moves, failures, retries, the slowest
126
+ arrival) and every failure. A failed step or move does not stop either
127
+ test; the exit code is 1 at the end.
128
+ - `test read` reads the first `--size` GB (10^9 bytes) of a block device in
129
+ 4 MiB reads, with `O_DIRECT` where the file system allows it and otherwise
130
+ with the page cache dropped through `posix_fadvise`, and prints the rate in
131
+ MB/s (10^6 bytes per second). With `--baseline`, the rate measured through
132
+ a direct cable, it passes if it is at most `--margin` (3 %) slower. It only
133
+ reads, and it refuses a device that is mounted (or one of its partitions)
134
+ unless `--force` is given. It needs no unit.
135
+
136
+ A full-speed device that comes up as low speed or not at all gets one retry
137
+ (disconnect and connect again), which is counted and reported: the USB2517
138
+ can detect a full-speed device as low speed when the port reset comes early
139
+ in a frame (errata DS80000628A, Module 4). In `test enum` this holds for the
140
+ device ports in `--allow-full-speed`.
141
+
142
+ `--timeout` of a test is the time a device may take to appear or go; the
143
+ time per protocol command is set with `--timeout` before the word `test`.
144
+ `--poll` (0.05 s) is the time between scans of the USB tree.
145
+
146
+ ## Library
147
+
148
+ ```python
149
+ from u2xbar import Unit
150
+
151
+ with Unit() as unit: # or Unit(serial="..."), Unit(port="/dev/ttyACM0")
152
+ print(unit.version())
153
+ unit.connect(3, 2)
154
+ for port in unit.list():
155
+ print(port.port, port.host, port.vbus, port.data)
156
+ print(unit.measure().i5_ma)
157
+ ```
158
+
159
+ Each protocol command has a method, and `command(line)` sends any line.
160
+ Results are dataclasses; a value the unit gives as `-` is `None`. An `err`
161
+ reply raises `UnitError`, which carries the code. Events go to the
162
+ `on_event` callback, or wait for `poll_events()`.
163
+
164
+ ## Tests
165
+
166
+ ```
167
+ uv venv <venv>
168
+ VIRTUAL_ENV=<venv> uv pip install -e . --group test
169
+ <venv>/bin/python -m pytest
170
+ ```
171
+
172
+ The tests run the tool against a fake unit on a pseudo-terminal and need no
173
+ hardware. For the acceptance tests, a fake world ties the fake unit's
174
+ connection commands to a fake sysfs tree, with devices that are slow, come up
175
+ as low speed, appear on the wrong hub, stay behind, or never appear; a fake
176
+ kernel log, a file as the block device, and a fake dfu-util complete it. One
177
+ test reads this computer's kernel log and sysfs; it runs only with
178
+ `U2XBAR_REAL_SYSTEM=1`.
179
+
180
+ ### Integration tests
181
+
182
+ The integration tests (`tests/test_sim_integration.py`) run the tool against
183
+ the firmware simulator `u2xbar-sim` (`sim/` in the u2xbar-sw repository): the
184
+ firmware's core and protocol on the board model of its PC tests, served on a
185
+ pseudo-terminal in real time. They run only when `U2XBAR_SIM` names the
186
+ simulator binary:
187
+
188
+ ```
189
+ cmake -S ../sim -B <build> -G Ninja
190
+ cmake --build <build>
191
+ U2XBAR_SIM=<build>/u2xbar-sim <venv>/bin/python -m pytest tests/test_sim_integration.py
192
+ ```
193
+
194
+ Each test starts its own simulator, with its pty file in the test's
195
+ temporary directory, and stops it at the end, also when the test fails. A
196
+ test drives the simulated unit through the command line (`python -m u2xbar
197
+ --port <pty>`, one process per command) or through `Unit`; most tests run
198
+ both ways. The simulator's `state` query checks the simulated hardware: for
199
+ example, that a connected device port's switch selects the hub of its host
200
+ port and that its VBUS is on, or that the discharge FET comes on only after
201
+ VBUS went off. Injections change the simulated world: a device attached, a
202
+ fault that lasts past `fault_off_ms`, a computer that removes VBUS, the 5 V
203
+ rail, a chip that does not answer. The tests cover every command, the
204
+ parameters and their bounds, the error codes `syntax`, `range`, `state` and
205
+ `hw` (the simulator cannot make an I2C transfer time out), events, `run`,
206
+ `raw`, `shell`, `measure --csv`, `--json` and the exit codes. A hardware-rule
207
+ violation of the board model fails the test.
208
+
209
+ `scripts/check.sh` in the repository builds the simulator and runs these
210
+ tests with the other checks.
211
+
212
+ ## How it was written
213
+
214
+ The code and documentation are written with
215
+ [Claude Code](https://claude.com/claude-code), using Anthropic's Claude Opus
216
+ 5.5 model.
@@ -0,0 +1,37 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Mete Balci
3
+
4
+ [build-system]
5
+ requires = ["setuptools>=77"]
6
+ build-backend = "setuptools.build_meta"
7
+
8
+ [project]
9
+ name = "u2xbar"
10
+ version = "0.1.0"
11
+ description = "Control tool and library for the u2xbar USB crossbar"
12
+ readme = "README.md"
13
+ license = "MIT"
14
+ license-files = ["LICENSE"]
15
+ authors = [{ name = "Mete Balci" }]
16
+ requires-python = ">=3.10"
17
+ dependencies = ["pyserial>=3.5"]
18
+ classifiers = [
19
+ "Development Status :: 2 - Pre-Alpha",
20
+ "Environment :: Console",
21
+ "Intended Audience :: Developers",
22
+ "Operating System :: OS Independent",
23
+ "Programming Language :: Python :: 3",
24
+ "Topic :: System :: Hardware :: Universal Serial Bus (USB)",
25
+ ]
26
+
27
+ [project.urls]
28
+ Repository = "https://github.com/metebalci/u2xbar-sw"
29
+
30
+ [project.scripts]
31
+ u2xbar = "u2xbar.cli:run"
32
+
33
+ [dependency-groups]
34
+ test = ["pytest>=7"]
35
+
36
+ [tool.pytest.ini_options]
37
+ testpaths = ["tests"]
u2xbar-0.1.0/setup.cfg ADDED
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,25 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Mete Balci
3
+
4
+ """Control tool and library for the u2xbar USB crossbar."""
5
+
6
+ from .discovery import FoundUnit, find_unit, list_units
7
+ from .errors import (
8
+ NoUnitError, ProtocolError, RequestError, SeveralUnitsError, U2xbarError, UnitError,
9
+ UnitTimeout,
10
+ )
11
+ from .protocol import Client, Event, Record
12
+ from .records import (
13
+ DevPort, HostDetach, HostPort, HubBoost, Measurement, Param, RegBlock, Status,
14
+ UnitInfo, Version,
15
+ )
16
+ from .unit import Unit
17
+
18
+ __version__ = "0.1.0"
19
+
20
+ __all__ = [
21
+ "Client", "DevPort", "Event", "FoundUnit", "HostDetach", "HostPort", "HubBoost",
22
+ "Measurement", "NoUnitError", "Param", "ProtocolError", "Record", "RegBlock",
23
+ "RequestError", "SeveralUnitsError", "Status", "U2xbarError", "Unit", "UnitError",
24
+ "UnitInfo", "UnitTimeout", "Version", "find_unit", "list_units",
25
+ ]
@@ -0,0 +1,6 @@
1
+ # SPDX-License-Identifier: MIT
2
+ # Copyright (c) 2026 Mete Balci
3
+
4
+ from .cli import run
5
+
6
+ run()