|
29 | 29 |
|
30 | 30 | PACKET_SIZE = 128 |
31 | 31 | PACKET_1K_SIZE = 1024 |
| 32 | +OTA_TRIGGER = bytes([0x12, 0x34, 0x56, 0x78]) |
32 | 33 |
|
33 | 34 |
|
34 | 35 | class SerialConsole: |
@@ -131,6 +132,18 @@ def build_header_payload(file_path: Path) -> bytes: |
131 | 132 | return payload.ljust(PACKET_SIZE, b"\0") |
132 | 133 |
|
133 | 134 |
|
| 135 | +def wait_for_boot_menu_withinapp(cmd_port: serial.Serial, console: SerialConsole, seconds: float) -> None: |
| 136 | + print("Waiting for bootloader menu on USART1...") |
| 137 | + deadline = time.monotonic() + seconds |
| 138 | + |
| 139 | + while time.monotonic() < deadline: |
| 140 | + time.sleep(0.05) |
| 141 | + console.poll() |
| 142 | + if console.contains("READY") or console.contains("Commands:"): |
| 143 | + return |
| 144 | + |
| 145 | + raise TimeoutError("Bootloader menu was not detected on the command UART") |
| 146 | + |
134 | 147 | def wait_for_boot_menu(cmd_port: serial.Serial, console: SerialConsole, seconds: float) -> None: |
135 | 148 | print("Reset the board now. Sending 'B' repeatedly on the command UART...") |
136 | 149 | deadline = time.monotonic() + seconds |
@@ -209,6 +222,12 @@ def transfer_file( |
209 | 222 | print("Ymodem transfer finished.") |
210 | 223 |
|
211 | 224 |
|
| 225 | +def send_ota_trigger(data_port: serial.Serial) -> None: |
| 226 | + print("Sending OTA trigger to APP on USART2...") |
| 227 | + data_port.write(OTA_TRIGGER) |
| 228 | + data_port.flush() |
| 229 | + |
| 230 | + |
212 | 231 | def parse_args() -> argparse.Namespace: |
213 | 232 | parser = argparse.ArgumentParser(description="Send APP image to STM32 bootloader over two UARTs") |
214 | 233 | parser.add_argument("--cmd-port", required=True, help="Command/debug UART, typically USART1 (for example COM5)") |
@@ -238,11 +257,23 @@ def main() -> int: |
238 | 257 |
|
239 | 258 | console = SerialConsole(cmd_port, "cmd") |
240 | 259 |
|
241 | | - wait_for_boot_menu(cmd_port, console, args.boot_window) |
| 260 | + send_ota_trigger(data_port) |
| 261 | + |
| 262 | + time.sleep(0.5) |
| 263 | + |
| 264 | + cmd_port.reset_input_buffer() |
| 265 | + data_port.reset_input_buffer() |
| 266 | + |
| 267 | + wait_for_boot_menu_withinapp(cmd_port, console, args.boot_window) |
| 268 | + |
| 269 | + #wait_for_boot_menu(cmd_port, console, args.boot_window) |
242 | 270 | print("Bootloader menu detected, sending command '2'...") |
243 | 271 | send_command(cmd_port, b"2", console) |
244 | 272 | transfer_file(data_port, file_path, console, args.retries) |
245 | 273 |
|
| 274 | + print("Sending OTA trigger...") |
| 275 | + send_ota_trigger(data_port) |
| 276 | + |
246 | 277 | print("Waiting for final bootloader output...") |
247 | 278 | time.sleep(1.0) |
248 | 279 | console.poll() |
|
0 commit comments