|
11 | 11 |
|
12 | 12 | import struct |
13 | 13 | import time |
| 14 | +from dataclasses import dataclass |
14 | 15 |
|
15 | 16 | import serial |
16 | 17 |
|
|
26 | 27 | } |
27 | 28 |
|
28 | 29 |
|
| 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 | + |
29 | 44 | def cobs_decode(data: bytes) -> bytes: |
30 | 45 | """Decode data using SPIKE Prime's COBS variant.""" |
31 | 46 | buffer = bytearray() |
@@ -95,41 +110,25 @@ def pack(data: bytes) -> bytes: |
95 | 110 | return bytes(buffer) |
96 | 111 |
|
97 | 112 |
|
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}") |
133 | 132 |
|
134 | 133 |
|
135 | 134 | def send_message(ser: serial.Serial, payload: bytes) -> None: |
@@ -184,13 +183,12 @@ def reboot_for_update_spike_prime(ser: serial.Serial) -> bool: |
184 | 183 | if not msg or msg[0] != 0x01: |
185 | 184 | return False |
186 | 185 |
|
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) |
190 | 188 |
|
191 | | - if fw_major < 1 or fw_minor < 7: |
| 189 | + if (info.fw_major, info.fw_minor) < (1, 8): |
192 | 190 | 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." |
194 | 192 | ) |
195 | 193 | return False |
196 | 194 |
|
|
0 commit comments