silabs-pycommander 1.0.0__py3-none-win_amd64.whl
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.
- pycommander/__init__.py +33 -0
- pycommander/__main__.py +18 -0
- pycommander/cli.py +41 -0
- silabs_pycommander-1.0.0.dist-info/METADATA +256 -0
- silabs_pycommander-1.0.0.dist-info/RECORD +8 -0
- silabs_pycommander-1.0.0.dist-info/WHEEL +5 -0
- silabs_pycommander-1.0.0.dist-info/entry_points.txt +2 -0
- silabs_pycommander-1.0.0.dist-info/licenses/LICENSE.md +8 -0
pycommander/__init__.py
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"""
|
|
2
|
+
License
|
|
3
|
+
Copyright 2026 Silicon Laboratories Inc. www.silabs.com
|
|
4
|
+
*******************************************************************************
|
|
5
|
+
The licensor of this software is Silicon Laboratories Inc. Your use of this
|
|
6
|
+
software is governed by the terms of Silicon Labs Master Software License
|
|
7
|
+
Agreement (MSLA) available at
|
|
8
|
+
www.silabs.com/about-us/legal/master-software-license-agreement. This
|
|
9
|
+
software is distributed to you in Source Code format and is governed by the
|
|
10
|
+
sections of the MSLA applicable to Source Code.
|
|
11
|
+
*******************************************************************************
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
try:
|
|
15
|
+
from pycommander_gui import Commander, CommanderResult, Adapter, Target, AemStream, __version__
|
|
16
|
+
except ImportError:
|
|
17
|
+
try:
|
|
18
|
+
from pycommander_cli import Commander, CommanderResult, Adapter, Target, AemStream, __version__
|
|
19
|
+
except ImportError:
|
|
20
|
+
raise ImportError(
|
|
21
|
+
"No version of Simplicity Commander is installed. Install one of the following packages:\n\n"
|
|
22
|
+
" pip install silabs-pycommander-cli\n"
|
|
23
|
+
" pip install silabs-pycommander-gui\n"
|
|
24
|
+
)
|
|
25
|
+
|
|
26
|
+
__all__ = [
|
|
27
|
+
"Commander",
|
|
28
|
+
"CommanderResult",
|
|
29
|
+
"Adapter",
|
|
30
|
+
"Target",
|
|
31
|
+
"AemStream",
|
|
32
|
+
"__version__",
|
|
33
|
+
]
|
pycommander/__main__.py
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""
|
|
2
|
+
License
|
|
3
|
+
Copyright 2026 Silicon Laboratories Inc. www.silabs.com
|
|
4
|
+
*******************************************************************************
|
|
5
|
+
The licensor of this software is Silicon Laboratories Inc. Your use of this
|
|
6
|
+
software is governed by the terms of Silicon Labs Master Software License
|
|
7
|
+
Agreement (MSLA) available at
|
|
8
|
+
www.silabs.com/about-us/legal/master-software-license-agreement. This
|
|
9
|
+
software is distributed to you in Source Code format and is governed by the
|
|
10
|
+
sections of the MSLA applicable to Source Code.
|
|
11
|
+
*******************************************************************************
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
# Entry point for `pycommander` command and `python3 -m pycommander`
|
|
15
|
+
from .cli import main
|
|
16
|
+
|
|
17
|
+
if __name__ == "__main__":
|
|
18
|
+
raise SystemExit(main())
|
pycommander/cli.py
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
"""
|
|
2
|
+
License
|
|
3
|
+
Copyright 2026 Silicon Laboratories Inc. www.silabs.com
|
|
4
|
+
*******************************************************************************
|
|
5
|
+
The licensor of this software is Silicon Laboratories Inc. Your use of this
|
|
6
|
+
software is governed by the terms of Silicon Labs Master Software License
|
|
7
|
+
Agreement (MSLA) available at
|
|
8
|
+
www.silabs.com/about-us/legal/master-software-license-agreement. This
|
|
9
|
+
software is distributed to you in Source Code format and is governed by the
|
|
10
|
+
sections of the MSLA applicable to Source Code.
|
|
11
|
+
*******************************************************************************
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
import sys
|
|
15
|
+
|
|
16
|
+
from pycommander_core.cli import PyCommanderCLI
|
|
17
|
+
|
|
18
|
+
try:
|
|
19
|
+
from pycommander_gui import Commander
|
|
20
|
+
CLI = False
|
|
21
|
+
|
|
22
|
+
except ImportError:
|
|
23
|
+
try:
|
|
24
|
+
from pycommander_cli import Commander
|
|
25
|
+
CLI = True
|
|
26
|
+
|
|
27
|
+
except ImportError:
|
|
28
|
+
raise ImportError(
|
|
29
|
+
"No version of Simplicity Commander is installed.\n\n"
|
|
30
|
+
"Install either of the following packages:\n"
|
|
31
|
+
" pip install silabs-pycommander-cli\n"
|
|
32
|
+
" pip install silabs-pycommander-gui\n"
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def main() -> int:
|
|
36
|
+
cli = PyCommanderCLI(cli=CLI)
|
|
37
|
+
args = sys.argv[1:] # Skip the script name
|
|
38
|
+
return cli.run(*args)
|
|
39
|
+
|
|
40
|
+
if __name__ == "__main__":
|
|
41
|
+
raise SystemExit(main())
|
|
@@ -0,0 +1,256 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: silabs-pycommander
|
|
3
|
+
Version: 1.0.0
|
|
4
|
+
Summary: Python library for Silicon Labs Simplicity Commander
|
|
5
|
+
Author: Silicon Labs
|
|
6
|
+
License-Expression: LicenseRef-MSLA
|
|
7
|
+
License-File: LICENSE.md
|
|
8
|
+
Requires-Python: >=3.10
|
|
9
|
+
Requires-Dist: silabs-pycommander-cli==1.0.0
|
|
10
|
+
Requires-Dist: silabs-pycommander-core==1.0.0
|
|
11
|
+
Provides-Extra: gui
|
|
12
|
+
Requires-Dist: silabs-pycommander-gui==1.0.0; extra == 'gui'
|
|
13
|
+
Description-Content-Type: text/markdown
|
|
14
|
+
|
|
15
|
+
# Silicon Labs PyCommander
|
|
16
|
+
|
|
17
|
+
[](https://github.com/SiliconLabsSoftware/pycommander/actions/workflows/unittest-and-coverage.yml)
|
|
18
|
+
|
|
19
|
+
## Introduction
|
|
20
|
+
|
|
21
|
+
This Python package wraps Simplicity Commander functionality and exposes a native Python API for interacting with Commander in your scripts.
|
|
22
|
+
|
|
23
|
+
## Requirements
|
|
24
|
+
|
|
25
|
+
This package requires Python 3.10 or newer. Required PyPI packages are:
|
|
26
|
+
|
|
27
|
+
- platformdirs
|
|
28
|
+
- pyyaml
|
|
29
|
+
|
|
30
|
+
Additionally, Simplicity Commander requires the SEGGER J-Link drivers to be installed on your system.
|
|
31
|
+
|
|
32
|
+
## Installation
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
pip install silabs-pycommander
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## Usage
|
|
39
|
+
|
|
40
|
+
More details about Simplicity Commander and its Command Line Interface can be found in the [official documentation for Simplicity Commander](https://docs.silabs.com/simplicity-commander/latest/simplicity-commander-start/). The documentation is also helpful when using the Python API, as the command names and available options are the same.
|
|
41
|
+
|
|
42
|
+
### Command Line Interface
|
|
43
|
+
|
|
44
|
+
From the command line, `pycommander` is a razor-thin wrapper around the Simplicity Commander CLI; it behaves exactly like the Simplicity Commander CLI, except for the case when the options `-v` or `--version` are passed as arguments, in which case the version of the `pycommander` package is printed in addition to the normal version information from the Simplicity Commander CLI.
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
pycommander --help
|
|
48
|
+
pycommander --version
|
|
49
|
+
pycommander <command> [options]
|
|
50
|
+
pycommander <command> <subcommand> [options]
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
### Python API
|
|
54
|
+
|
|
55
|
+
At the lowest level, the `Commander` class provides all the CLI commands as methods to the class. These methods return a dictionary containing the command output, similarly to what the Simplicity Commander CLI does when the `--json` flag is used.
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from pycommander import Commander
|
|
59
|
+
|
|
60
|
+
# Instantiate the Commander class with a serial number
|
|
61
|
+
commander = Commander(serial_number="44055955")
|
|
62
|
+
|
|
63
|
+
# Perform the 'commander device info' command
|
|
64
|
+
print(commander.device.info(target_device="EFR32MG24"))
|
|
65
|
+
|
|
66
|
+
# Perform the 'commander util appinfo' command
|
|
67
|
+
print(commander.util.appinfo(filename="firmware.hex"))
|
|
68
|
+
|
|
69
|
+
# Perform the 'commander flash' command
|
|
70
|
+
print(commander.flash.flash(filenames=["firmware.hex"], address=0x08000000))
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The `Commander` class also exposes a few standalone helpers; for example, `getVersion()` returns the embedded Simplicity Commander, J-Link, EMDLL and other component versions as a `CommanderVersionInfo` object:
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
from pycommander import Commander
|
|
77
|
+
|
|
78
|
+
commander = Commander()
|
|
79
|
+
|
|
80
|
+
# Get the version of the embedded Simplicity Commander, J-Link, EMDLL and other components
|
|
81
|
+
print(commander.getVersion())
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
`listAvailableAdapters()` is a helper method that can be used to (unintrusively) scan for available adapters. This method returns a list of `BasicAdapterInfo` objects, each carrying `jlink_serial_number`, `ip_address` and `nickname` (any of which may be `None`):
|
|
85
|
+
|
|
86
|
+
```python
|
|
87
|
+
from pycommander import Commander
|
|
88
|
+
|
|
89
|
+
commander = Commander()
|
|
90
|
+
|
|
91
|
+
# List USB adapters
|
|
92
|
+
adapters = commander.listAvailableAdapters(list_usb_adapters=True)
|
|
93
|
+
for adapter in adapters:
|
|
94
|
+
print(adapter.jlink_serial_number, adapter.nickname)
|
|
95
|
+
|
|
96
|
+
# List network adapters
|
|
97
|
+
adapters = commander.listAvailableAdapters(list_network_adapters=True)
|
|
98
|
+
for adapter in adapters:
|
|
99
|
+
print(adapter.ip_address, adapter.nickname)
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
Please note that not all commands are available to the `Commander` class. These are typically commands that are intended for interative CLI sessions, and include command suites like `vcom`, `vuart`, `rtt` and `swo`. Moreover, some commands in the `Commander` class have stricter requirements for the arguments than their CLI counterparts, for the same reasons as mentioned above. For example, the `aem dump` command requires the `outfile` and `duration` arguments to be provided. For a more flexible approach to streaming AEM data, please see the `AemStream` class below.
|
|
103
|
+
|
|
104
|
+
For ad-hoc invocations of commands that are not exposed by the typed API, you can fall back to `Commander.runCommand(...)`, which forwards arguments directly to the underlying Simplicity Commander CLI:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
# Run a raw Commander CLI command and capture its output
|
|
108
|
+
result = commander.runCommand("rtt", "--help", json_formatted_output=False)
|
|
109
|
+
print(result.output)
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
#### The `Adapter` and `Target` classes
|
|
113
|
+
|
|
114
|
+
pycommander exposes several convenience methods for common tasks related to the adapter and the target device. These methods return different data types depending on the command. The types are available in the `pycommander_core.types` module, and the tasks include:
|
|
115
|
+
|
|
116
|
+
- Locking/unlocking the device for debug access
|
|
117
|
+
- Setting the CTUNE value
|
|
118
|
+
- Setting the adapter's VCOM configuration
|
|
119
|
+
- Configuring the target device's voltage
|
|
120
|
+
- Flashing firmware to the device
|
|
121
|
+
- Erasing the device's flash
|
|
122
|
+
- Configuring code regions (Series 3 only)
|
|
123
|
+
- +++
|
|
124
|
+
|
|
125
|
+
When instantiating the `Adapter` class, a `Commander` class instance is created and made available as an attribute of the `Adapter` class. If a `target_device` is provided to the `Adapter` class, a `Target` class instance is created and made available as an attribute of the `Adapter` class as well.
|
|
126
|
+
|
|
127
|
+
An `Adapter` class instance (with a potential `Target` class instance) should be used to represent a connection to a single adapter (with target device). Multiple `Adapter` class instances can be used to represent connections to multiple adapters (with or without their respective target devices):
|
|
128
|
+
|
|
129
|
+
```python
|
|
130
|
+
from pycommander import Adapter
|
|
131
|
+
|
|
132
|
+
serial_numbers = ["44055955", "44055956", "44055957"]
|
|
133
|
+
adapters = [Adapter(serial_number=sn, target_device="EFR32MG24") for sn in serial_numbers]
|
|
134
|
+
for adapter in adapters:
|
|
135
|
+
print(adapter.info())
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
A typical session against a single adapter may look like this:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from pycommander import Adapter
|
|
142
|
+
from pycommander_core.types import AdapterInfo, AdapterVoltageInfo, VcomHandshake, CtuneValue
|
|
143
|
+
|
|
144
|
+
# Instantiate the Adapter class with a serial number and target device
|
|
145
|
+
adapter = Adapter(serial_number="44055955", target_device="EFR32MG24")
|
|
146
|
+
|
|
147
|
+
# Get the adapter information
|
|
148
|
+
adapter_info: AdapterInfo = adapter.info()
|
|
149
|
+
|
|
150
|
+
# Get the voltage information
|
|
151
|
+
voltage_info: AdapterVoltageInfo | None = adapter.getVoltage()
|
|
152
|
+
|
|
153
|
+
# Set the VCOM configuration of the adapter
|
|
154
|
+
adapter.setVcomConfig(115200, VcomHandshake.RTSCTS, True)
|
|
155
|
+
|
|
156
|
+
# Get the CTUNE value of the target device
|
|
157
|
+
ctune_value: CtuneValue = adapter.target.getCTUNE()
|
|
158
|
+
|
|
159
|
+
# Set the CTUNE value of the target device
|
|
160
|
+
adapter.target.setCTUNE(ctune_value.board)
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
A common high-level task is flashing firmware. `Target.flashApplication()` accepts one or more files (`.hex`, `.s37`, `.bin`, `.gbl` or `.rps`) and handles the underlying flash, verify and reset steps:
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
from pathlib import Path
|
|
167
|
+
from pycommander import Adapter
|
|
168
|
+
|
|
169
|
+
adapter = Adapter(serial_number="44055955", target_device="EFR32MG24")
|
|
170
|
+
|
|
171
|
+
success: bool = adapter.target.flashApplication(filenames=[Path("firmware.hex")])
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### The `AemStream` class
|
|
175
|
+
|
|
176
|
+
The `AemStream` class provides a pythonic way of streaming AEM measurements from the device. The measurements are returned as `AemMeasurement` objects, which contain the timestamp, current, voltage, and the calculated power. An `AemStream` object is suitable for streaming AEM measurements from an adapter, and there is no limitation to the duration of the streaming. The stream may be stopped at any time.
|
|
177
|
+
|
|
178
|
+
Like the underlying Simplicity Commander CLI, the `AemStream` class supports a variety of options for configuring the AEM data capture process, like setting up simple triggers to start the data capture process and specifying the data output rate.
|
|
179
|
+
|
|
180
|
+
##### Context Manager Syntax
|
|
181
|
+
|
|
182
|
+
If using the context manager syntax, the `AemStream` object is opened automatically when the context manager is entered, and a connection to the adapter is established. The connection is cleanly closed when the context manager is exited.
|
|
183
|
+
|
|
184
|
+
```python
|
|
185
|
+
from pycommander import AemStream
|
|
186
|
+
from pycommander_core.types import AemMeasurement
|
|
187
|
+
|
|
188
|
+
# Instantiate a 10 second AEM stream with a data output rate of 100 Hz
|
|
189
|
+
with AemStream(serial_number="44055955", datarate_hz=100, duration_s=10) as aem_stream:
|
|
190
|
+
for measurement in aem_stream:
|
|
191
|
+
print(measurement)
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
##### Manual Syntax
|
|
195
|
+
|
|
196
|
+
The `AemStream` class can also be instantiated without using the context manager syntax. In this case, the `open()` method must be called to open the connection to the adapter and start the data capture process, and the `close()` method must be called to gracefully stop the data capture process and close the connection.
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
from pycommander import AemStream
|
|
200
|
+
from pycommander_core.types import AemMeasurement
|
|
201
|
+
|
|
202
|
+
# Instantiate the AemStream class with a serial number and a set data rate
|
|
203
|
+
aem_stream : AemStream = AemStream(serial_number="44055955", datarate_hz=100)
|
|
204
|
+
|
|
205
|
+
# Open the AEM stream
|
|
206
|
+
aem_stream.open()
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
some_condition : bool = False
|
|
210
|
+
# Read the AEM measurements
|
|
211
|
+
for measurement in aem_stream:
|
|
212
|
+
# Do something
|
|
213
|
+
# ...
|
|
214
|
+
|
|
215
|
+
if some_condition:
|
|
216
|
+
break
|
|
217
|
+
|
|
218
|
+
# Close the AEM stream
|
|
219
|
+
aem_stream.close()
|
|
220
|
+
```
|
|
221
|
+
|
|
222
|
+
#### Error handling
|
|
223
|
+
|
|
224
|
+
Failed Commander invocations raise typed exceptions, so your automation scripts can react to them in a structured way. Three exception classes are exposed from `pycommander_core.errors`:
|
|
225
|
+
|
|
226
|
+
- `PyCommanderInputError` — Commander rejected the arguments (return code -1 / 255).
|
|
227
|
+
- `PyCommanderRuntimeError` — Commander failed at runtime, e.g. the adapter could not be reached or the operation timed out (return code -2 / 254).
|
|
228
|
+
- `PyCommanderError` — base class for any other non-zero return code, and parent of the two above.
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from pathlib import Path
|
|
232
|
+
from pycommander import Adapter
|
|
233
|
+
from pycommander_core.errors import PyCommanderError, PyCommanderRuntimeError
|
|
234
|
+
|
|
235
|
+
adapter = Adapter(serial_number="44055955", target_device="EFR32MG24")
|
|
236
|
+
|
|
237
|
+
try:
|
|
238
|
+
adapter.target.flashApplication(filenames=[Path("firmware.hex")])
|
|
239
|
+
except PyCommanderRuntimeError as e:
|
|
240
|
+
print(f"Commander failed at runtime: {e}")
|
|
241
|
+
except PyCommanderError as e:
|
|
242
|
+
print(f"Other Commander error: {e}")
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
#### Logging
|
|
246
|
+
|
|
247
|
+
All Commander invocations can be logged to a file by passing the `log_file_path` argument to the `Commander` constructor. Each invocation is recorded with a timestamp, which is handy when diagnosing issues in long-running automations or production-test rigs.
|
|
248
|
+
|
|
249
|
+
```python
|
|
250
|
+
from pathlib import Path
|
|
251
|
+
from pycommander import Adapter, Commander
|
|
252
|
+
|
|
253
|
+
# Build a Commander with logging enabled, then attach it to an Adapter
|
|
254
|
+
commander = Commander(serial_number="44055955", log_file_path=Path("pycommander.log"))
|
|
255
|
+
adapter = Adapter(commander=commander, target_device="EFR32MG24")
|
|
256
|
+
```
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
pycommander/__init__.py,sha256=tVPuL--OziChrtVqBPcBnBDUxwQfXxOp7YoFfvmDJ-U,1223
|
|
2
|
+
pycommander/__main__.py,sha256=gFZy40pgofsCWow4ZosWqz604lv3_r-_RKmoYFlY_oY,773
|
|
3
|
+
pycommander/cli.py,sha256=P0QL7O93pvTOCkq5Cdji9n0HpgxkEiYIVEb7801ATwk,1289
|
|
4
|
+
silabs_pycommander-1.0.0.dist-info/METADATA,sha256=BONAqg5jmLccfZb4w1FcXDb1ezZX42ATrfDPofwCVS4,11115
|
|
5
|
+
silabs_pycommander-1.0.0.dist-info/WHEEL,sha256=uRY8Y8b0jIsgox8TvbI2NzR6A6HgEPOoY9Q5yFXfv18,95
|
|
6
|
+
silabs_pycommander-1.0.0.dist-info/entry_points.txt,sha256=geYHoZQeYZqGmLrVorSjB-fKYkPojsJFldhf9-kspp8,53
|
|
7
|
+
silabs_pycommander-1.0.0.dist-info/licenses/LICENSE.md,sha256=vJYbYTyTIBbmTzK2-DjPFgYaDM9ZvsSaN7QtKPBJxqM,575
|
|
8
|
+
silabs_pycommander-1.0.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
**Copyright 2026 Silicon Laboratories Inc. [https://www.silabs.com](https://www.silabs.com/)**
|
|
2
|
+
|
|
3
|
+
SPDX-License-Identifier: LicenseRef-MSLA
|
|
4
|
+
|
|
5
|
+
The licensor of this software is Silicon Laboratories Inc.
|
|
6
|
+
Your use of this software is governed by the terms of the Silicon Labs Master Software License Agreement (MSLA) available at
|
|
7
|
+
[https://www.silabs.com/about-us/legal/master-software-license-agreement](https://www.silabs.com/about-us/legal/master-software-license-agreement).
|
|
8
|
+
By installing, copying or otherwise using this software, you agree to the terms of the MSLA.
|