Skip to content

Commit 4529f76

Browse files
committed
tools/flash: Clean up version parser.
1 parent 48d3058 commit 4529f76

1 file changed

Lines changed: 38 additions & 40 deletions

File tree

tools/flash/serdev/spike.py

Lines changed: 38 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
import struct
1313
import time
14+
from dataclasses import dataclass
1415

1516
import serial
1617

@@ -26,6 +27,20 @@
2627
}
2728

2829

30+
@dataclass
31+
class InfoResponse:
32+
rpc_major: int
33+
rpc_minor: int
34+
rpc_build: int
35+
fw_major: int
36+
fw_minor: int
37+
fw_build: int
38+
max_packet: int
39+
max_message: int
40+
max_chunk: int
41+
device_type: int
42+
43+
2944
def cobs_decode(data: bytes) -> bytes:
3045
"""Decode data using SPIKE Prime's COBS variant."""
3146
buffer = bytearray()
@@ -95,41 +110,25 @@ def pack(data: bytes) -> bytes:
95110
return bytes(buffer)
96111

97112

98-
def decode_info_response(msg: bytes):
99-
"""Decode a 0x01 InfoResponse into named fields (all little-endian)."""
100-
(
101-
_type,
102-
rpc_major,
103-
rpc_minor,
104-
rpc_build,
105-
fw_major,
106-
fw_minor,
107-
fw_build,
108-
max_packet,
109-
max_message,
110-
max_chunk,
111-
device_type,
112-
) = struct.unpack("<BBBHBBHHHHH", msg[:17])
113-
return [
114-
("RPC version", f"{rpc_major}.{rpc_minor} build {rpc_build}"),
115-
("Firmware version", f"{fw_major}.{fw_minor} build {fw_build}"),
116-
("Max packet size", max_packet),
117-
("Max message size", max_message),
118-
("Max chunk size", max_chunk),
119-
("Product group device type", device_type),
120-
]
121-
122-
123-
def print_message(direction: str, msg: bytes) -> None:
124-
"""Pretty-print a single decoded protocol message."""
125-
if not msg:
126-
return
127-
msg_id = msg[0]
128-
name = MSG_NAMES.get(msg_id, f"Unknown(0x{msg_id:02x})")
129-
print(f"{direction} 0x{msg_id:02x} {name} ({len(msg)}) {msg.hex(' ')}")
130-
if msg_id == 0x01:
131-
for field, value in decode_info_response(msg):
132-
print(f" - {field:<26} {value}")
113+
def decode_info_response(msg: bytes) -> InfoResponse:
114+
if len(msg) < 17 or msg[0] != 0x01:
115+
raise ValueError("Invalid InfoResponse message")
116+
"""Decode a 0x01 InfoResponse payload (all little-endian)."""
117+
return InfoResponse(*struct.unpack("<BBHBBHHHHH", msg[1:17]))
118+
119+
120+
def print_info_response(info: InfoResponse) -> None:
121+
"""Pretty-print a decoded InfoResponse."""
122+
print(
123+
f" - {'RPC version':<26} {info.rpc_major}.{info.rpc_minor} build {info.rpc_build}"
124+
)
125+
print(
126+
f" - {'Firmware version':<26} {info.fw_major}.{info.fw_minor} build {info.fw_build}"
127+
)
128+
print(f" - {'Max packet size':<26} {info.max_packet}")
129+
print(f" - {'Max message size':<26} {info.max_message}")
130+
print(f" - {'Max chunk size':<26} {info.max_chunk}")
131+
print(f" - {'Product group device type':<26} {info.device_type}")
133132

134133

135134
def send_message(ser: serial.Serial, payload: bytes) -> None:
@@ -184,13 +183,12 @@ def reboot_for_update_spike_prime(ser: serial.Serial) -> bool:
184183
if not msg or msg[0] != 0x01:
185184
return False
186185

187-
# Extract firmware version from the InfoResponse.
188-
# Layout: type(B) rpc_major(B) rpc_minor(B) rpc_build(H) fw_major(B) fw_minor(B) ...
189-
_, _, _, _, fw_major, fw_minor = struct.unpack_from("<BBBHBB", msg)
186+
info = decode_info_response(msg)
187+
print_info_response(info)
190188

191-
if fw_major < 1 or fw_minor < 7:
189+
if (info.fw_major, info.fw_minor) < (1, 8):
192190
print(
193-
f"SPIKE Prime firmware {fw_major}.{fw_minor} is too old to reboot to update mode."
191+
f"SPIKE Prime firmware {info.fw_major}.{info.fw_minor} is too old to reboot to update mode."
194192
)
195193
return False
196194

0 commit comments

Comments
 (0)