pypicoboot 1.2__py3-none-any.whl → 1.3__py3-none-any.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.
- picoboot/__init__.py +1 -0
- picoboot/_version.py +1 -1
- picoboot/core/__init__.py +1 -0
- picoboot/core/exceptions.py +28 -0
- picoboot/picoboot.py +20 -10
- {pypicoboot-1.2.dist-info → pypicoboot-1.3.dist-info}/METADATA +1 -1
- pypicoboot-1.3.dist-info/RECORD +14 -0
- pypicoboot-1.2.dist-info/RECORD +0 -13
- {pypicoboot-1.2.dist-info → pypicoboot-1.3.dist-info}/WHEEL +0 -0
- {pypicoboot-1.2.dist-info → pypicoboot-1.3.dist-info}/top_level.txt +0 -0
picoboot/__init__.py
CHANGED
picoboot/_version.py
CHANGED
picoboot/core/__init__.py
CHANGED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"""
|
|
2
|
+
/*
|
|
3
|
+
* This file is part of the pypicoboot distribution (https://github.com/polhenarejos/pypicoboot).
|
|
4
|
+
* Copyright (c) 2025 Pol Henarejos.
|
|
5
|
+
*
|
|
6
|
+
* This program is free software: you can redistribute it and/or modify
|
|
7
|
+
* it under the terms of the GNU Affero General Public License as published by
|
|
8
|
+
* the Free Software Foundation, version 3.
|
|
9
|
+
*
|
|
10
|
+
* This program is distributed in the hope that it will be useful, but
|
|
11
|
+
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
12
|
+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
13
|
+
* Affero General Public License for more details.
|
|
14
|
+
*
|
|
15
|
+
* You should have received a copy of the GNU Affero General Public License
|
|
16
|
+
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
17
|
+
*/
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
class PicoBootError(Exception):
|
|
22
|
+
pass
|
|
23
|
+
|
|
24
|
+
class PicoBootNotFoundError(PicoBootError):
|
|
25
|
+
pass
|
|
26
|
+
|
|
27
|
+
class PicoBootInvalidStateError(PicoBootError):
|
|
28
|
+
pass
|
picoboot/picoboot.py
CHANGED
|
@@ -27,6 +27,7 @@ from .utils import uint_to_int
|
|
|
27
27
|
from .core.enums import NamedIntEnum
|
|
28
28
|
from .picobootmonitor import PicoBootMonitor, PicoBootMonitorObserver
|
|
29
29
|
from .core.log import get_logger
|
|
30
|
+
from .core.exceptions import PicoBootError, PicoBootNotFoundError, PicoBootInvalidStateError
|
|
30
31
|
|
|
31
32
|
logger = get_logger("PicoBoot")
|
|
32
33
|
|
|
@@ -134,9 +135,6 @@ class Model(NamedIntEnum):
|
|
|
134
135
|
class Addresses(NamedIntEnum):
|
|
135
136
|
BOOTROM_MAGIC = 0x00000010
|
|
136
137
|
|
|
137
|
-
class PicoBootError(Exception):
|
|
138
|
-
pass
|
|
139
|
-
|
|
140
138
|
class PicoBoot:
|
|
141
139
|
|
|
142
140
|
def __init__(self, dev: usb.core.Device, intf, ep_out, ep_in) -> None:
|
|
@@ -193,7 +191,7 @@ class PicoBoot:
|
|
|
193
191
|
devices = list(devices) if devices is not None else []
|
|
194
192
|
if not devices:
|
|
195
193
|
logger.error("No device found in PICOBOOT mode")
|
|
196
|
-
raise
|
|
194
|
+
raise PicoBootNotFoundError("No device found in PICOBOOT mode")
|
|
197
195
|
|
|
198
196
|
dev = None
|
|
199
197
|
if serial is None:
|
|
@@ -211,7 +209,7 @@ class PicoBoot:
|
|
|
211
209
|
break
|
|
212
210
|
if dev is None:
|
|
213
211
|
logger.error("No device found with this serial number")
|
|
214
|
-
raise
|
|
212
|
+
raise PicoBootNotFoundError("No device found with this serial number")
|
|
215
213
|
|
|
216
214
|
# Ensure active configuration
|
|
217
215
|
# macOS does not allow detach_kernel_driver, and often returns Access Denied
|
|
@@ -240,7 +238,7 @@ class PicoBoot:
|
|
|
240
238
|
break
|
|
241
239
|
if intf is None:
|
|
242
240
|
logger.error("No interface found with PICOBOOT at the device")
|
|
243
|
-
raise
|
|
241
|
+
raise PicoBootNotFoundError("No interface found with PICOBOOT at the device")
|
|
244
242
|
|
|
245
243
|
#usb.util.claim_interface(dev, intf.bInterfaceNumber)
|
|
246
244
|
|
|
@@ -256,7 +254,7 @@ class PicoBoot:
|
|
|
256
254
|
|
|
257
255
|
if ep_in is None or ep_out is None:
|
|
258
256
|
logger.error("No PICOBOOT BULK_IN/BULK_OUT endpoints found")
|
|
259
|
-
raise
|
|
257
|
+
raise PicoBootNotFoundError("No PICOBOOT BULK_IN/BULK_OUT endpoints found")
|
|
260
258
|
logger.info("PICOBOOT device opened successfully.")
|
|
261
259
|
return cls(dev, intf, ep_out, ep_in)
|
|
262
260
|
|
|
@@ -348,7 +346,11 @@ class PicoBoot:
|
|
|
348
346
|
logger.debug(f"Sending command {cmd_id} (0x{cmd_id:02X}) with token {token} (0x{token:08X}) and transfer_length {transfer_length}")
|
|
349
347
|
|
|
350
348
|
logger.trace(f"Command header: {hexlify(header).decode()}")
|
|
351
|
-
|
|
349
|
+
try:
|
|
350
|
+
self.ep_out.write(header, timeout=timeout)
|
|
351
|
+
except usb.core.USBError as e:
|
|
352
|
+
logger.error(f"Failed to send command header: {e}")
|
|
353
|
+
raise PicoBootInvalidStateError("Failed to send command header: " + str(e))
|
|
352
354
|
logger.debug(f"Command header sent: {hexlify(header).decode()}")
|
|
353
355
|
|
|
354
356
|
data_in = b""
|
|
@@ -359,7 +361,11 @@ class PicoBoot:
|
|
|
359
361
|
chunks = []
|
|
360
362
|
maxpkt = self.ep_in.wMaxPacketSize
|
|
361
363
|
while remaining > 0:
|
|
362
|
-
|
|
364
|
+
try:
|
|
365
|
+
chunk = bytes(self.ep_in.read(min(maxpkt, remaining), timeout=timeout))
|
|
366
|
+
except usb.core.USBError as e:
|
|
367
|
+
logger.error(f"Failed to read data_in: {e}")
|
|
368
|
+
raise PicoBootInvalidStateError("Failed to read data_in: " + str(e))
|
|
363
369
|
if not chunk:
|
|
364
370
|
break
|
|
365
371
|
chunks.append(chunk)
|
|
@@ -374,7 +380,11 @@ class PicoBoot:
|
|
|
374
380
|
logger.error("data_out missing or too short for OUT command")
|
|
375
381
|
raise ValueError("data_out missing or too short for OUT command")
|
|
376
382
|
logger.trace(f"Sending data_out: {hexlify(data_out[:transfer_length]).decode()}")
|
|
377
|
-
|
|
383
|
+
try:
|
|
384
|
+
self.ep_out.write(data_out[:transfer_length], timeout=timeout)
|
|
385
|
+
except usb.core.USBError as e:
|
|
386
|
+
logger.error(f"Failed to send data_out: {e}")
|
|
387
|
+
raise PicoBootInvalidStateError("Failed to send data_out: " + str(e))
|
|
378
388
|
|
|
379
389
|
try:
|
|
380
390
|
logger.debug("Waiting for ACK...")
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
picoboot/__init__.py,sha256=L3OuhBO-lBObxfIWfshCvoncMsyGVNRgmIHfB1--gpg,165
|
|
2
|
+
picoboot/_version.py,sha256=DXz0dzWxoWHXwhXhaO2JM-ZexTVtNfW6wegSuu761Rw,776
|
|
3
|
+
picoboot/picoboot.py,sha256=j4HH-21alARli7LzI1TY8NAne9TAahU_mJ1SjAoz2iE,25592
|
|
4
|
+
picoboot/picobootmonitor.py,sha256=3msEP2S8ZS7P8QVgKpq9Z9Rcud78XygmG1_0L_OZOvs,2443
|
|
5
|
+
picoboot/utils.py,sha256=SjpAoPZrgyD9Ws7NIFVBHt0zPOb8Lpu2_lsmfeT2rXE,1083
|
|
6
|
+
picoboot/core/__init__.py,sha256=c1kJprnljn0eP1NR3wEw-wJSCSxSRF3DA2jF5MowHXk,57
|
|
7
|
+
picoboot/core/enums.py,sha256=ugXS-dbdnusLib_ge0vT1OugHVG9ZjJfpUR073MhwdQ,1353
|
|
8
|
+
picoboot/core/exceptions.py,sha256=AXilq0ViaXyA6Ls9aGx6DHE9TQyPacQbwnHBXgFD3EQ,909
|
|
9
|
+
picoboot/core/log.py,sha256=XWtN_hgmOtvpDMGDg-9f2BDLUe8elqUAbWti5yCJAA0,1768
|
|
10
|
+
picoboot/tools/picotool.py,sha256=e2xjIxP5UZn9yfjxUWkJXq6KQHyw4YsGbuQbTauo0-Q,94
|
|
11
|
+
pypicoboot-1.3.dist-info/METADATA,sha256=x36b7kZmd_TiPAYXK0MWYhBewLLsfNVUEHiapHvcic4,41109
|
|
12
|
+
pypicoboot-1.3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
13
|
+
pypicoboot-1.3.dist-info/top_level.txt,sha256=sjegZQO5-kQdFOXXJHm0P7Hg1Nw4Ri0WKHnRYDTsa4I,9
|
|
14
|
+
pypicoboot-1.3.dist-info/RECORD,,
|
pypicoboot-1.2.dist-info/RECORD
DELETED
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
picoboot/__init__.py,sha256=cQPxH_qPx7ph9SQ-Z4Jc2YCU3SKYnDta6wzU-Q65suc,72
|
|
2
|
-
picoboot/_version.py,sha256=j-dtPcfbhr1IMhFhudY5UZVclyBgMpxp0yoDa7RLwT4,776
|
|
3
|
-
picoboot/picoboot.py,sha256=uzmd9W9JLNXCMSk4U0NzCnMCNAc4xnQg7es1lEJeN9A,24831
|
|
4
|
-
picoboot/picobootmonitor.py,sha256=3msEP2S8ZS7P8QVgKpq9Z9Rcud78XygmG1_0L_OZOvs,2443
|
|
5
|
-
picoboot/utils.py,sha256=SjpAoPZrgyD9Ws7NIFVBHt0zPOb8Lpu2_lsmfeT2rXE,1083
|
|
6
|
-
picoboot/core/__init__.py,sha256=fmoYRI4KbzhLjXblEs_H9zgdCs7oDuSKeNEG_-kMgYo,32
|
|
7
|
-
picoboot/core/enums.py,sha256=ugXS-dbdnusLib_ge0vT1OugHVG9ZjJfpUR073MhwdQ,1353
|
|
8
|
-
picoboot/core/log.py,sha256=XWtN_hgmOtvpDMGDg-9f2BDLUe8elqUAbWti5yCJAA0,1768
|
|
9
|
-
picoboot/tools/picotool.py,sha256=e2xjIxP5UZn9yfjxUWkJXq6KQHyw4YsGbuQbTauo0-Q,94
|
|
10
|
-
pypicoboot-1.2.dist-info/METADATA,sha256=GgnGeLWZEcQDGmvC7stKpgCrMxdlbKXF4h1UxGamc30,41109
|
|
11
|
-
pypicoboot-1.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
-
pypicoboot-1.2.dist-info/top_level.txt,sha256=sjegZQO5-kQdFOXXJHm0P7Hg1Nw4Ri0WKHnRYDTsa4I,9
|
|
13
|
-
pypicoboot-1.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|