pytactl 2.0.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.
- pytactl-2.0.0/LICENSE +26 -0
- pytactl-2.0.0/PKG-INFO +265 -0
- pytactl-2.0.0/README.md +221 -0
- pytactl-2.0.0/pyproject.toml +104 -0
- pytactl-2.0.0/pytactl/__init__.py +43 -0
- pytactl-2.0.0/pytactl/cli.py +220 -0
- pytactl-2.0.0/pytactl/debugboard.py +1054 -0
- pytactl-2.0.0/pytactl/installconfigs.py +138 -0
- pytactl-2.0.0/pytactl/service.py +152 -0
- pytactl-2.0.0/pytactl/shell.py +93 -0
- pytactl-2.0.0/pytactl/tac_configs/TAC_FTDI_13.tcnf +392 -0
- pytactl-2.0.0/pytactl.egg-info/PKG-INFO +265 -0
- pytactl-2.0.0/pytactl.egg-info/SOURCES.txt +19 -0
- pytactl-2.0.0/pytactl.egg-info/dependency_links.txt +1 -0
- pytactl-2.0.0/pytactl.egg-info/entry_points.txt +2 -0
- pytactl-2.0.0/pytactl.egg-info/requires.txt +13 -0
- pytactl-2.0.0/pytactl.egg-info/top_level.txt +1 -0
- pytactl-2.0.0/setup.cfg +4 -0
- pytactl-2.0.0/tests/test_config_loading.py +129 -0
- pytactl-2.0.0/tests/test_create_board.py +198 -0
- pytactl-2.0.0/tests/test_smoke.py +31 -0
pytactl-2.0.0/LICENSE
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries.
|
|
2
|
+
|
|
3
|
+
Redistribution and use in source and binary forms, with or without
|
|
4
|
+
modification, are permitted provided that the following conditions are
|
|
5
|
+
met:
|
|
6
|
+
* Redistributions of source code must retain the above copyright
|
|
7
|
+
notice, this list of conditions and the following disclaimer.
|
|
8
|
+
* Redistributions in binary form must reproduce the above
|
|
9
|
+
copyright notice, this list of conditions and the following
|
|
10
|
+
disclaimer in the documentation and/or other materials provided
|
|
11
|
+
with the distribution.
|
|
12
|
+
* Neither the name of the copyright holder nor the names of its
|
|
13
|
+
contributors may be used to endorse or promote products derived
|
|
14
|
+
from this software without specific prior written permission.
|
|
15
|
+
|
|
16
|
+
THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
|
|
17
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
|
|
19
|
+
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
|
|
20
|
+
BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
21
|
+
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
22
|
+
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
|
23
|
+
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
|
24
|
+
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
|
25
|
+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
|
|
26
|
+
IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
pytactl-2.0.0/PKG-INFO
ADDED
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pytactl
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: Python Test Automation Controller (TAC/Alpaca) for Qualcomm debug boards
|
|
5
|
+
Author-email: "Qualcomm Technologies, Inc." <qc.opensource@qti.qualcomm.com>
|
|
6
|
+
Maintainer-email: Milosz Wasilewski <milosz.wasilewski@oss.qualcomm.com>
|
|
7
|
+
License-Expression: BSD-3-Clause
|
|
8
|
+
Project-URL: Homepage, https://github.com/qualcomm/pytactl
|
|
9
|
+
Project-URL: Repository, https://github.com/qualcomm/pytactl
|
|
10
|
+
Project-URL: Issues, https://github.com/qualcomm/pytactl/issues
|
|
11
|
+
Project-URL: Documentation, https://github.com/qualcomm/pytactl/blob/main/README.md
|
|
12
|
+
Project-URL: Security Policy, https://github.com/qualcomm/pytactl/blob/main/SECURITY.md
|
|
13
|
+
Keywords: debug-board,hardware,qualcomm,tac,test-automation
|
|
14
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
15
|
+
Classifier: Environment :: Console
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Classifier: Operating System :: MacOS
|
|
18
|
+
Classifier: Operating System :: Microsoft :: Windows
|
|
19
|
+
Classifier: Operating System :: POSIX :: Linux
|
|
20
|
+
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
23
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
25
|
+
Classifier: Topic :: Software Development :: Embedded Systems
|
|
26
|
+
Classifier: Topic :: Software Development :: Testing
|
|
27
|
+
Classifier: Topic :: System :: Hardware
|
|
28
|
+
Requires-Python: >=3.10
|
|
29
|
+
Description-Content-Type: text/markdown
|
|
30
|
+
License-File: LICENSE
|
|
31
|
+
Requires-Dist: Flask
|
|
32
|
+
Requires-Dist: Flask-RESTful
|
|
33
|
+
Requires-Dist: pyftdi
|
|
34
|
+
Requires-Dist: pyusb
|
|
35
|
+
Requires-Dist: pexpect
|
|
36
|
+
Requires-Dist: pyserial
|
|
37
|
+
Requires-Dist: requests
|
|
38
|
+
Requires-Dist: platformdirs
|
|
39
|
+
Requires-Dist: hid
|
|
40
|
+
Provides-Extra: dev
|
|
41
|
+
Requires-Dist: ruff==0.15.17; extra == "dev"
|
|
42
|
+
Requires-Dist: pytest; extra == "dev"
|
|
43
|
+
Dynamic: license-file
|
|
44
|
+
|
|
45
|
+
# pytactl
|
|
46
|
+
|
|
47
|
+
Python implementation of Test Automation Controller (TAC/Alpaca) for controlling Qualcomm debug boards.
|
|
48
|
+
It uses config files and PSOC firmware from the original TAC (Alpaca) system.
|
|
49
|
+
|
|
50
|
+
# Installation
|
|
51
|
+
|
|
52
|
+
Install the `pytactl` command on your system from [PyPI](https://pypi.org/project/pytactl/)
|
|
53
|
+
with [pipx](https://pipx.pypa.io):
|
|
54
|
+
|
|
55
|
+
pipx install pytactl
|
|
56
|
+
|
|
57
|
+
To install from a checkout of this repository instead:
|
|
58
|
+
|
|
59
|
+
pipx install .
|
|
60
|
+
|
|
61
|
+
This puts a single `pytactl` entry point on your `PATH`. Note that the `hid`
|
|
62
|
+
dependency needs `libhidapi` package to be installed (required for Bughopper V2 boards).
|
|
63
|
+
|
|
64
|
+
Alternatively, for development in a virtualenv:
|
|
65
|
+
|
|
66
|
+
virtualenv -p python3 venv
|
|
67
|
+
. ./venv/bin/activate
|
|
68
|
+
pip install -e .
|
|
69
|
+
|
|
70
|
+
Run `pytactl -h` to see all available options.
|
|
71
|
+
|
|
72
|
+
## System dependencies
|
|
73
|
+
|
|
74
|
+
pytactl uses `hidapi` for HID-based debug boards, including Bughopper V2.
|
|
75
|
+
Install the native HIDAPI library before installing or running `pytactl`.
|
|
76
|
+
|
|
77
|
+
### Ubuntu / Debian
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
sudo apt update
|
|
81
|
+
sudo apt install -y libhidapi-hidraw0 libhidapi-libusb0
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
### Fedora
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
sudo dnf install -y hidapi
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
## USB permissions
|
|
91
|
+
|
|
92
|
+
By default, USB devices are not accessible without root. Create a udev rule for your board:
|
|
93
|
+
|
|
94
|
+
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9302", MODE="0666", GROUP="plugdev"' \
|
|
95
|
+
| sudo tee /etc/udev/rules.d/99-alpaca.rules
|
|
96
|
+
sudo udevadm control --reload-rules && sudo udevadm trigger
|
|
97
|
+
|
|
98
|
+
Bughopper V2 also exposes a HID interface, so it needs a `hidraw` rule:
|
|
99
|
+
|
|
100
|
+
echo 'SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="b001", MODE="0660", GROUP="plugdev", TAG+="uaccess"' \
|
|
101
|
+
| sudo tee /etc/udev/rules.d/99-bughopper-v2.rules
|
|
102
|
+
sudo udevadm control --reload-rules && sudo udevadm trigger
|
|
103
|
+
|
|
104
|
+
Then make sure your user is in the `plugdev` group (log out and back in after):
|
|
105
|
+
|
|
106
|
+
sudo usermod -aG plugdev $USER
|
|
107
|
+
|
|
108
|
+
# Configuration
|
|
109
|
+
|
|
110
|
+
**Bughopper boards (V1 and V2) work out of the box.** They are self-describing and need no
|
|
111
|
+
config files.
|
|
112
|
+
|
|
113
|
+
**All other debug boards (FTDI, PSOC) require configuration files** that are NOT shipped with
|
|
114
|
+
pytactl. The easiest way to obtain them is the `installconfigs` subcommand, which downloads every
|
|
115
|
+
`.tcnf` file and `devicelist.json` from the
|
|
116
|
+
[qcom-test-automation-controller](https://github.com/qualcomm/qcom-test-automation-controller/tree/main/configurations)
|
|
117
|
+
project:
|
|
118
|
+
|
|
119
|
+
pytactl installconfigs
|
|
120
|
+
|
|
121
|
+
With no arguments it fetches from the default config repository and installs into a per-user
|
|
122
|
+
data directory (resolved with [platformdirs](https://pypi.org/project/platformdirs/), e.g.
|
|
123
|
+
`~/.local/share/pytactl` on Linux). Once that directory is populated, the board subcommands use it
|
|
124
|
+
automatically as the default `--tac-config-path`. Override either with:
|
|
125
|
+
|
|
126
|
+
pytactl installconfigs \
|
|
127
|
+
--config-repository https://github.com/qualcomm/qcom-test-automation-controller/ \
|
|
128
|
+
--local-path /path/to/install \
|
|
129
|
+
--ref main \
|
|
130
|
+
--repository-path configurations
|
|
131
|
+
|
|
132
|
+
`--ref` selects the git ref (branch, tag, or commit; default `HEAD`) and `--repository-path` the
|
|
133
|
+
directory within the repository to fetch from (default `configurations`).
|
|
134
|
+
|
|
135
|
+
`installconfigs` also copies the default FTDI Alpaca-Lite config (which has no upstream `.tcnf`
|
|
136
|
+
file) in as `default.tcnf` and rewrites empty `configPath` entries in `devicelist.json` to point
|
|
137
|
+
at it.
|
|
138
|
+
|
|
139
|
+
You can also copy the `configurations/` directory by hand and point pytactl at it with
|
|
140
|
+
`--tac-config-path <dir>`.
|
|
141
|
+
|
|
142
|
+
Note: some configs in qcom-test-automation-controller currently have syntax issues; pick the
|
|
143
|
+
ones that match your board.
|
|
144
|
+
|
|
145
|
+
`devicelist.json` maps board hardware IDs to their `.tcnf` config files, and must be present in
|
|
146
|
+
the `--tac-config-path` directory for FTDI/PSOC boards. Example entry for a PSOC board:
|
|
147
|
+
|
|
148
|
+
{
|
|
149
|
+
"catalog": [
|
|
150
|
+
{
|
|
151
|
+
"platform_id": 17,
|
|
152
|
+
"configPath": "tac_configs/TAC_PSOC_17.tcnf"
|
|
153
|
+
}
|
|
154
|
+
]
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
## Finding your board's serial number
|
|
158
|
+
|
|
159
|
+
The `--serial` argument takes the USB serial number, not a device path. The easiest way to
|
|
160
|
+
discover connected boards and their serial numbers is the `list` subcommand:
|
|
161
|
+
|
|
162
|
+
pytactl list
|
|
163
|
+
|
|
164
|
+
It prints every recognised debug board with its type, USB vendor/product ID, and serial number
|
|
165
|
+
(read from udev, the same `ID_SERIAL_SHORT` value you pass to `--serial`):
|
|
166
|
+
|
|
167
|
+
Connected debug boards:
|
|
168
|
+
Bughopper V1 vid:pid=0403:6015 serial=DP05DIAN
|
|
169
|
+
PSOC vid:pid=05c6:9302 serial=0123456789
|
|
170
|
+
|
|
171
|
+
Alternatively, find it manually with `udevadm`:
|
|
172
|
+
|
|
173
|
+
udevadm info /dev/ttyACM0 | grep ID_SERIAL_SHORT
|
|
174
|
+
|
|
175
|
+
Or using `lsusb` (replace `VID:PID` with `0403:6011` for FTDI or `05c6:9302` for PSOC):
|
|
176
|
+
|
|
177
|
+
lsusb -v -d VID:PID | grep iSerial
|
|
178
|
+
|
|
179
|
+
# Using as a shell
|
|
180
|
+
|
|
181
|
+
Start the interactive shell with the `shell` subcommand:
|
|
182
|
+
|
|
183
|
+
pytactl shell --serial <ID_SERIAL_SHORT>
|
|
184
|
+
|
|
185
|
+
Optional arguments:
|
|
186
|
+
|
|
187
|
+
--tac-config-path <dir> # path to config directory (required for FTDI/PSOC boards, see Configuration)
|
|
188
|
+
--log-level DEBUG # log verbosity (default: DEBUG)
|
|
189
|
+
|
|
190
|
+
Once started, the shell prompt accepts commands generated from your board's config script. The available commands depend on the config — not all boards define every command (e.g. newer configs may omit `powerOn`/`powerOff`). Typical commands:
|
|
191
|
+
|
|
192
|
+
**Power control:**
|
|
193
|
+
|
|
194
|
+
powerOn
|
|
195
|
+
powerOff
|
|
196
|
+
devicePowerOn
|
|
197
|
+
devicePowerOff
|
|
198
|
+
usbDevicePowerOn
|
|
199
|
+
usbDevicePowerOff
|
|
200
|
+
|
|
201
|
+
**Boot modes:**
|
|
202
|
+
|
|
203
|
+
bootToEDL
|
|
204
|
+
bootToFastboot
|
|
205
|
+
bootToUEFI
|
|
206
|
+
reset
|
|
207
|
+
|
|
208
|
+
**GPIO pins** (use with `1` to assert, `0` to deassert):
|
|
209
|
+
|
|
210
|
+
pkey 1 # press power key
|
|
211
|
+
pkey 0 # release power key
|
|
212
|
+
volup 1
|
|
213
|
+
voldn 1
|
|
214
|
+
|
|
215
|
+
Type `help` in the shell to list all commands available for your specific board.
|
|
216
|
+
|
|
217
|
+
# Running a single command
|
|
218
|
+
|
|
219
|
+
Use the `oneshot` subcommand to run one command and exit, without entering the interactive
|
|
220
|
+
shell. This is handy for scripting:
|
|
221
|
+
|
|
222
|
+
pytactl oneshot bootToEDL --serial <ID_SERIAL_SHORT>
|
|
223
|
+
pytactl oneshot reset --serial <ID_SERIAL_SHORT>
|
|
224
|
+
|
|
225
|
+
GPIO pin commands take an integer value (`1` to assert, `0` to deassert):
|
|
226
|
+
|
|
227
|
+
pytactl oneshot pkey 1 --serial <ID_SERIAL_SHORT>
|
|
228
|
+
pytactl oneshot pkey 0 --serial <ID_SERIAL_SHORT>
|
|
229
|
+
|
|
230
|
+
The same commands available in the shell can be used here. An unknown command exits with an
|
|
231
|
+
error listing the commands supported by your board.
|
|
232
|
+
|
|
233
|
+
# Using as a service
|
|
234
|
+
|
|
235
|
+
pytactl service --serial <ID_SERIAL_SHORT_1> [<ID_SERIAL_SHORT_2> ...]
|
|
236
|
+
|
|
237
|
+
The REST API runs on `http://localhost:5000`. Example usage with curl:
|
|
238
|
+
|
|
239
|
+
# List connected boards
|
|
240
|
+
curl http://localhost:5000/
|
|
241
|
+
|
|
242
|
+
# List available quick methods (bootToEDL, powerOn, etc.)
|
|
243
|
+
curl http://localhost:5000/<boardid>/quick
|
|
244
|
+
|
|
245
|
+
# Power on/off
|
|
246
|
+
curl -X PUT http://localhost:5000/<boardid>/quick/powerOn
|
|
247
|
+
curl -X PUT http://localhost:5000/<boardid>/quick/powerOff
|
|
248
|
+
|
|
249
|
+
# Boot to EDL
|
|
250
|
+
curl -X PUT http://localhost:5000/<boardid>/quick/bootToEDL
|
|
251
|
+
|
|
252
|
+
# Boot to fastboot
|
|
253
|
+
curl -X PUT http://localhost:5000/<boardid>/quick/bootToFastboot
|
|
254
|
+
|
|
255
|
+
# Set a named pin
|
|
256
|
+
curl -X PUT "http://localhost:5000/<boardid>/command/reset?value=1"
|
|
257
|
+
|
|
258
|
+
# Set a raw pin (e.g., bus A, pin 0)
|
|
259
|
+
curl -X PUT "http://localhost:5000/<boardid>/pin/A0?value=1"
|
|
260
|
+
|
|
261
|
+
Note: REST API server runs in debug mode. Running with multiple concurrent threads may lead to unexpected behaviour.
|
|
262
|
+
|
|
263
|
+
# License
|
|
264
|
+
|
|
265
|
+
pytactl is licensed under the [BSD-3-clause License](https://spdx.org/licenses/BSD-3-Clause.html). See [LICENSE](LICENSE) for the full license text.
|
pytactl-2.0.0/README.md
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
# pytactl
|
|
2
|
+
|
|
3
|
+
Python implementation of Test Automation Controller (TAC/Alpaca) for controlling Qualcomm debug boards.
|
|
4
|
+
It uses config files and PSOC firmware from the original TAC (Alpaca) system.
|
|
5
|
+
|
|
6
|
+
# Installation
|
|
7
|
+
|
|
8
|
+
Install the `pytactl` command on your system from [PyPI](https://pypi.org/project/pytactl/)
|
|
9
|
+
with [pipx](https://pipx.pypa.io):
|
|
10
|
+
|
|
11
|
+
pipx install pytactl
|
|
12
|
+
|
|
13
|
+
To install from a checkout of this repository instead:
|
|
14
|
+
|
|
15
|
+
pipx install .
|
|
16
|
+
|
|
17
|
+
This puts a single `pytactl` entry point on your `PATH`. Note that the `hid`
|
|
18
|
+
dependency needs `libhidapi` package to be installed (required for Bughopper V2 boards).
|
|
19
|
+
|
|
20
|
+
Alternatively, for development in a virtualenv:
|
|
21
|
+
|
|
22
|
+
virtualenv -p python3 venv
|
|
23
|
+
. ./venv/bin/activate
|
|
24
|
+
pip install -e .
|
|
25
|
+
|
|
26
|
+
Run `pytactl -h` to see all available options.
|
|
27
|
+
|
|
28
|
+
## System dependencies
|
|
29
|
+
|
|
30
|
+
pytactl uses `hidapi` for HID-based debug boards, including Bughopper V2.
|
|
31
|
+
Install the native HIDAPI library before installing or running `pytactl`.
|
|
32
|
+
|
|
33
|
+
### Ubuntu / Debian
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
sudo apt update
|
|
37
|
+
sudo apt install -y libhidapi-hidraw0 libhidapi-libusb0
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Fedora
|
|
41
|
+
|
|
42
|
+
```bash
|
|
43
|
+
sudo dnf install -y hidapi
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## USB permissions
|
|
47
|
+
|
|
48
|
+
By default, USB devices are not accessible without root. Create a udev rule for your board:
|
|
49
|
+
|
|
50
|
+
echo 'SUBSYSTEM=="usb", ATTR{idVendor}=="05c6", ATTR{idProduct}=="9302", MODE="0666", GROUP="plugdev"' \
|
|
51
|
+
| sudo tee /etc/udev/rules.d/99-alpaca.rules
|
|
52
|
+
sudo udevadm control --reload-rules && sudo udevadm trigger
|
|
53
|
+
|
|
54
|
+
Bughopper V2 also exposes a HID interface, so it needs a `hidraw` rule:
|
|
55
|
+
|
|
56
|
+
echo 'SUBSYSTEM=="hidraw", ATTRS{idVendor}=="2341", ATTRS{idProduct}=="b001", MODE="0660", GROUP="plugdev", TAG+="uaccess"' \
|
|
57
|
+
| sudo tee /etc/udev/rules.d/99-bughopper-v2.rules
|
|
58
|
+
sudo udevadm control --reload-rules && sudo udevadm trigger
|
|
59
|
+
|
|
60
|
+
Then make sure your user is in the `plugdev` group (log out and back in after):
|
|
61
|
+
|
|
62
|
+
sudo usermod -aG plugdev $USER
|
|
63
|
+
|
|
64
|
+
# Configuration
|
|
65
|
+
|
|
66
|
+
**Bughopper boards (V1 and V2) work out of the box.** They are self-describing and need no
|
|
67
|
+
config files.
|
|
68
|
+
|
|
69
|
+
**All other debug boards (FTDI, PSOC) require configuration files** that are NOT shipped with
|
|
70
|
+
pytactl. The easiest way to obtain them is the `installconfigs` subcommand, which downloads every
|
|
71
|
+
`.tcnf` file and `devicelist.json` from the
|
|
72
|
+
[qcom-test-automation-controller](https://github.com/qualcomm/qcom-test-automation-controller/tree/main/configurations)
|
|
73
|
+
project:
|
|
74
|
+
|
|
75
|
+
pytactl installconfigs
|
|
76
|
+
|
|
77
|
+
With no arguments it fetches from the default config repository and installs into a per-user
|
|
78
|
+
data directory (resolved with [platformdirs](https://pypi.org/project/platformdirs/), e.g.
|
|
79
|
+
`~/.local/share/pytactl` on Linux). Once that directory is populated, the board subcommands use it
|
|
80
|
+
automatically as the default `--tac-config-path`. Override either with:
|
|
81
|
+
|
|
82
|
+
pytactl installconfigs \
|
|
83
|
+
--config-repository https://github.com/qualcomm/qcom-test-automation-controller/ \
|
|
84
|
+
--local-path /path/to/install \
|
|
85
|
+
--ref main \
|
|
86
|
+
--repository-path configurations
|
|
87
|
+
|
|
88
|
+
`--ref` selects the git ref (branch, tag, or commit; default `HEAD`) and `--repository-path` the
|
|
89
|
+
directory within the repository to fetch from (default `configurations`).
|
|
90
|
+
|
|
91
|
+
`installconfigs` also copies the default FTDI Alpaca-Lite config (which has no upstream `.tcnf`
|
|
92
|
+
file) in as `default.tcnf` and rewrites empty `configPath` entries in `devicelist.json` to point
|
|
93
|
+
at it.
|
|
94
|
+
|
|
95
|
+
You can also copy the `configurations/` directory by hand and point pytactl at it with
|
|
96
|
+
`--tac-config-path <dir>`.
|
|
97
|
+
|
|
98
|
+
Note: some configs in qcom-test-automation-controller currently have syntax issues; pick the
|
|
99
|
+
ones that match your board.
|
|
100
|
+
|
|
101
|
+
`devicelist.json` maps board hardware IDs to their `.tcnf` config files, and must be present in
|
|
102
|
+
the `--tac-config-path` directory for FTDI/PSOC boards. Example entry for a PSOC board:
|
|
103
|
+
|
|
104
|
+
{
|
|
105
|
+
"catalog": [
|
|
106
|
+
{
|
|
107
|
+
"platform_id": 17,
|
|
108
|
+
"configPath": "tac_configs/TAC_PSOC_17.tcnf"
|
|
109
|
+
}
|
|
110
|
+
]
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
## Finding your board's serial number
|
|
114
|
+
|
|
115
|
+
The `--serial` argument takes the USB serial number, not a device path. The easiest way to
|
|
116
|
+
discover connected boards and their serial numbers is the `list` subcommand:
|
|
117
|
+
|
|
118
|
+
pytactl list
|
|
119
|
+
|
|
120
|
+
It prints every recognised debug board with its type, USB vendor/product ID, and serial number
|
|
121
|
+
(read from udev, the same `ID_SERIAL_SHORT` value you pass to `--serial`):
|
|
122
|
+
|
|
123
|
+
Connected debug boards:
|
|
124
|
+
Bughopper V1 vid:pid=0403:6015 serial=DP05DIAN
|
|
125
|
+
PSOC vid:pid=05c6:9302 serial=0123456789
|
|
126
|
+
|
|
127
|
+
Alternatively, find it manually with `udevadm`:
|
|
128
|
+
|
|
129
|
+
udevadm info /dev/ttyACM0 | grep ID_SERIAL_SHORT
|
|
130
|
+
|
|
131
|
+
Or using `lsusb` (replace `VID:PID` with `0403:6011` for FTDI or `05c6:9302` for PSOC):
|
|
132
|
+
|
|
133
|
+
lsusb -v -d VID:PID | grep iSerial
|
|
134
|
+
|
|
135
|
+
# Using as a shell
|
|
136
|
+
|
|
137
|
+
Start the interactive shell with the `shell` subcommand:
|
|
138
|
+
|
|
139
|
+
pytactl shell --serial <ID_SERIAL_SHORT>
|
|
140
|
+
|
|
141
|
+
Optional arguments:
|
|
142
|
+
|
|
143
|
+
--tac-config-path <dir> # path to config directory (required for FTDI/PSOC boards, see Configuration)
|
|
144
|
+
--log-level DEBUG # log verbosity (default: DEBUG)
|
|
145
|
+
|
|
146
|
+
Once started, the shell prompt accepts commands generated from your board's config script. The available commands depend on the config — not all boards define every command (e.g. newer configs may omit `powerOn`/`powerOff`). Typical commands:
|
|
147
|
+
|
|
148
|
+
**Power control:**
|
|
149
|
+
|
|
150
|
+
powerOn
|
|
151
|
+
powerOff
|
|
152
|
+
devicePowerOn
|
|
153
|
+
devicePowerOff
|
|
154
|
+
usbDevicePowerOn
|
|
155
|
+
usbDevicePowerOff
|
|
156
|
+
|
|
157
|
+
**Boot modes:**
|
|
158
|
+
|
|
159
|
+
bootToEDL
|
|
160
|
+
bootToFastboot
|
|
161
|
+
bootToUEFI
|
|
162
|
+
reset
|
|
163
|
+
|
|
164
|
+
**GPIO pins** (use with `1` to assert, `0` to deassert):
|
|
165
|
+
|
|
166
|
+
pkey 1 # press power key
|
|
167
|
+
pkey 0 # release power key
|
|
168
|
+
volup 1
|
|
169
|
+
voldn 1
|
|
170
|
+
|
|
171
|
+
Type `help` in the shell to list all commands available for your specific board.
|
|
172
|
+
|
|
173
|
+
# Running a single command
|
|
174
|
+
|
|
175
|
+
Use the `oneshot` subcommand to run one command and exit, without entering the interactive
|
|
176
|
+
shell. This is handy for scripting:
|
|
177
|
+
|
|
178
|
+
pytactl oneshot bootToEDL --serial <ID_SERIAL_SHORT>
|
|
179
|
+
pytactl oneshot reset --serial <ID_SERIAL_SHORT>
|
|
180
|
+
|
|
181
|
+
GPIO pin commands take an integer value (`1` to assert, `0` to deassert):
|
|
182
|
+
|
|
183
|
+
pytactl oneshot pkey 1 --serial <ID_SERIAL_SHORT>
|
|
184
|
+
pytactl oneshot pkey 0 --serial <ID_SERIAL_SHORT>
|
|
185
|
+
|
|
186
|
+
The same commands available in the shell can be used here. An unknown command exits with an
|
|
187
|
+
error listing the commands supported by your board.
|
|
188
|
+
|
|
189
|
+
# Using as a service
|
|
190
|
+
|
|
191
|
+
pytactl service --serial <ID_SERIAL_SHORT_1> [<ID_SERIAL_SHORT_2> ...]
|
|
192
|
+
|
|
193
|
+
The REST API runs on `http://localhost:5000`. Example usage with curl:
|
|
194
|
+
|
|
195
|
+
# List connected boards
|
|
196
|
+
curl http://localhost:5000/
|
|
197
|
+
|
|
198
|
+
# List available quick methods (bootToEDL, powerOn, etc.)
|
|
199
|
+
curl http://localhost:5000/<boardid>/quick
|
|
200
|
+
|
|
201
|
+
# Power on/off
|
|
202
|
+
curl -X PUT http://localhost:5000/<boardid>/quick/powerOn
|
|
203
|
+
curl -X PUT http://localhost:5000/<boardid>/quick/powerOff
|
|
204
|
+
|
|
205
|
+
# Boot to EDL
|
|
206
|
+
curl -X PUT http://localhost:5000/<boardid>/quick/bootToEDL
|
|
207
|
+
|
|
208
|
+
# Boot to fastboot
|
|
209
|
+
curl -X PUT http://localhost:5000/<boardid>/quick/bootToFastboot
|
|
210
|
+
|
|
211
|
+
# Set a named pin
|
|
212
|
+
curl -X PUT "http://localhost:5000/<boardid>/command/reset?value=1"
|
|
213
|
+
|
|
214
|
+
# Set a raw pin (e.g., bus A, pin 0)
|
|
215
|
+
curl -X PUT "http://localhost:5000/<boardid>/pin/A0?value=1"
|
|
216
|
+
|
|
217
|
+
Note: REST API server runs in debug mode. Running with multiple concurrent threads may lead to unexpected behaviour.
|
|
218
|
+
|
|
219
|
+
# License
|
|
220
|
+
|
|
221
|
+
pytactl is licensed under the [BSD-3-clause License](https://spdx.org/licenses/BSD-3-Clause.html). See [LICENSE](LICENSE) for the full license text.
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Copyright (c) 2026 Qualcomm Technologies, Inc. and/or its subsidiaries.
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
3
|
+
|
|
4
|
+
[build-system]
|
|
5
|
+
requires = ["setuptools>=77"]
|
|
6
|
+
build-backend = "setuptools.build_meta"
|
|
7
|
+
|
|
8
|
+
[project]
|
|
9
|
+
name = "pytactl"
|
|
10
|
+
dynamic = ["version"]
|
|
11
|
+
description = "Python Test Automation Controller (TAC/Alpaca) for Qualcomm debug boards"
|
|
12
|
+
readme = "README.md"
|
|
13
|
+
requires-python = ">=3.10"
|
|
14
|
+
license = "BSD-3-Clause"
|
|
15
|
+
license-files = ["LICENSE"]
|
|
16
|
+
authors = [
|
|
17
|
+
{ name = "Qualcomm Technologies, Inc.", email = "qc.opensource@qti.qualcomm.com" },
|
|
18
|
+
]
|
|
19
|
+
maintainers = [
|
|
20
|
+
{ name = "Milosz Wasilewski", email = "milosz.wasilewski@oss.qualcomm.com" },
|
|
21
|
+
]
|
|
22
|
+
keywords = [
|
|
23
|
+
"debug-board",
|
|
24
|
+
"hardware",
|
|
25
|
+
"qualcomm",
|
|
26
|
+
"tac",
|
|
27
|
+
"test-automation",
|
|
28
|
+
]
|
|
29
|
+
classifiers = [
|
|
30
|
+
"Development Status :: 5 - Production/Stable",
|
|
31
|
+
"Environment :: Console",
|
|
32
|
+
"Intended Audience :: Developers",
|
|
33
|
+
"Operating System :: MacOS",
|
|
34
|
+
"Operating System :: Microsoft :: Windows",
|
|
35
|
+
"Operating System :: POSIX :: Linux",
|
|
36
|
+
"Programming Language :: Python :: 3",
|
|
37
|
+
"Programming Language :: Python :: 3.10",
|
|
38
|
+
"Programming Language :: Python :: 3.11",
|
|
39
|
+
"Programming Language :: Python :: 3.12",
|
|
40
|
+
"Programming Language :: Python :: 3.13",
|
|
41
|
+
"Topic :: Software Development :: Embedded Systems",
|
|
42
|
+
"Topic :: Software Development :: Testing",
|
|
43
|
+
"Topic :: System :: Hardware",
|
|
44
|
+
]
|
|
45
|
+
dependencies = [
|
|
46
|
+
"Flask",
|
|
47
|
+
"Flask-RESTful",
|
|
48
|
+
"pyftdi",
|
|
49
|
+
"pyusb",
|
|
50
|
+
"pexpect",
|
|
51
|
+
"pyserial",
|
|
52
|
+
"requests",
|
|
53
|
+
"platformdirs",
|
|
54
|
+
"hid",
|
|
55
|
+
]
|
|
56
|
+
|
|
57
|
+
[project.optional-dependencies]
|
|
58
|
+
dev = ["ruff==0.15.17", "pytest"]
|
|
59
|
+
|
|
60
|
+
[project.scripts]
|
|
61
|
+
pytactl = "pytactl.cli:main"
|
|
62
|
+
|
|
63
|
+
[project.urls]
|
|
64
|
+
Homepage = "https://github.com/qualcomm/pytactl"
|
|
65
|
+
Repository = "https://github.com/qualcomm/pytactl"
|
|
66
|
+
Issues = "https://github.com/qualcomm/pytactl/issues"
|
|
67
|
+
Documentation = "https://github.com/qualcomm/pytactl/blob/main/README.md"
|
|
68
|
+
"Security Policy" = "https://github.com/qualcomm/pytactl/blob/main/SECURITY.md"
|
|
69
|
+
|
|
70
|
+
[tool.setuptools]
|
|
71
|
+
packages = ["pytactl"]
|
|
72
|
+
|
|
73
|
+
# Single source of truth for the version: pytactl/__init__.py
|
|
74
|
+
[tool.setuptools.dynamic]
|
|
75
|
+
version = { attr = "pytactl.__version__" }
|
|
76
|
+
|
|
77
|
+
[tool.setuptools.package-data]
|
|
78
|
+
pytactl = ["tac_configs/*"]
|
|
79
|
+
|
|
80
|
+
[tool.pytest.ini_options]
|
|
81
|
+
testpaths = ["tests"]
|
|
82
|
+
pythonpath = ["."]
|
|
83
|
+
|
|
84
|
+
# Ruff configuration (replaces black, isort and pylint)
|
|
85
|
+
[tool.ruff]
|
|
86
|
+
target-version = "py310"
|
|
87
|
+
line-length = 88
|
|
88
|
+
|
|
89
|
+
[tool.ruff.lint]
|
|
90
|
+
select = [
|
|
91
|
+
"E", # pycodestyle errors
|
|
92
|
+
"F", # pyflakes
|
|
93
|
+
"W", # pycodestyle warnings
|
|
94
|
+
"I", # isort (import ordering)
|
|
95
|
+
"UP", # pyupgrade
|
|
96
|
+
"B", # flake8-bugbear
|
|
97
|
+
"C4", # flake8-comprehensions
|
|
98
|
+
"SIM", # flake8-simplify
|
|
99
|
+
]
|
|
100
|
+
ignore = [
|
|
101
|
+
"E501", # line length is handled by the formatter
|
|
102
|
+
"B904", # raise-without-from inside except (matches old pylint W0707)
|
|
103
|
+
"SIM115", # open without a context manager (matches old pylint R1732)
|
|
104
|
+
]
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Copyright (c) 2025-2026 Qualcomm Technologies, Inc. and/or its subsidiaries.
|
|
2
|
+
# SPDX-License-Identifier: BSD-3-Clause
|
|
3
|
+
|
|
4
|
+
import os
|
|
5
|
+
|
|
6
|
+
import platformdirs
|
|
7
|
+
|
|
8
|
+
__version__ = "2.0.0"
|
|
9
|
+
|
|
10
|
+
# Configs bundled with the package. Only the synthesized FTDI Alpaca-Lite
|
|
11
|
+
# default (TAC_FTDI_13.tcnf) ships here; the full config set (every .tcnf plus
|
|
12
|
+
# devicelist.json) is fetched with the "installconfigs" subcommand.
|
|
13
|
+
PACKAGE_TAC_CONFIG_PATH = os.path.join(os.path.dirname(__file__), "tac_configs")
|
|
14
|
+
|
|
15
|
+
# Where "installconfigs" writes the full config set by default.
|
|
16
|
+
INSTALLED_TAC_CONFIG_PATH = platformdirs.user_data_dir("pytactl")
|
|
17
|
+
|
|
18
|
+
# Default config repository fetched by "installconfigs".
|
|
19
|
+
DEFAULT_CONFIG_REPOSITORY = (
|
|
20
|
+
"https://github.com/qualcomm/qcom-test-automation-controller/"
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
# Filename of the default FTDI Alpaca-Lite config used as a fallback. The upstream
|
|
24
|
+
# repository has no .tcnf for it (it is generated by FTDIPlatformConfiguration.cpp),
|
|
25
|
+
# so "installconfigs" copies the bundled TAC_FTDI_13.tcnf under this name.
|
|
26
|
+
DEFAULT_CONFIG_FILENAME = "default.tcnf"
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def default_tac_config_path():
|
|
30
|
+
"""Resolve the default TAC config directory.
|
|
31
|
+
|
|
32
|
+
Prefer the installed config set (populated by "installconfigs") when it
|
|
33
|
+
exists and is non-empty; otherwise fall back to the configs bundled with
|
|
34
|
+
the package.
|
|
35
|
+
"""
|
|
36
|
+
installed = INSTALLED_TAC_CONFIG_PATH
|
|
37
|
+
if os.path.isdir(installed) and os.listdir(installed):
|
|
38
|
+
return installed
|
|
39
|
+
return PACKAGE_TAC_CONFIG_PATH
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
# Backwards-compatible module-level default; resolved at import time.
|
|
43
|
+
DEFAULT_TAC_CONFIG_PATH = default_tac_config_path()
|