ra8-firmware 0.1.0
Bare-metal firmware for the Renesas RA8 family (RA8D2 / RA8P1)
Loading...
Searching...
No Matches
gen_jlink_w4.py
Go to the documentation of this file.
1#!/usr/bin/env python3
2# SPDX-License-Identifier: MIT
3# Copyright (c) 2026 Brighton Sikarskie
4"""Emit a J-Link script that programs MRAM with w4 and starts without a reset.
5
6Why w4 instead of loadfile/loadbin:
7 loadfile/loadbin both trigger SYSRESETREQ before programming. After that
8 reset the RA8D2 runs on its ~4 MHz internal oscillator; J-Link uploads
9 its RAMCode to SRAM and calls Prepare/Program/Finalize. After ~13
10 consecutive operations the MRAM controller accumulates error state that
11 only a physical PORST (power-on reset) can clear, causing every subsequent
12 flash attempt to fail.
13
14Why not "r" to restart after w4 writes:
15 J-Link Commander's "r" command on RA8D2 with TrustZone invokes a
16 device-specific reset sequence that again runs RAMCode Prepare(), causing
17 the same accumulation. Instead, the generated script injects the firmware
18 entry point directly into the CPU core registers via DCRSR/DCRDR while
19 the CPU is halted, then issues "g" (go). No SYSRESETREQ is issued at any
20 point, so the MRAM controller state never accumulates.
21
22DCRSR/DCRDR register injection (ARMv8-M reference manual, C1.6):
23 DCRDR (0xE000EDF8): data register -- write the value here first
24 DCRSR (0xE000EDF4): selector register -- set bit 16 (write) + reg index
25 Register indices used:
26 15 (0x0F) = PC
27 17 (0x11) = MSP
28 16 (0x10) = xPSR (set T bit, Thread mode: 0x01000000)
29 20 (0x14) = CFBP (CONTROL | FAULTMASK | BASEPRI | PRIMASK, all zero)
30
31Usage:
32 python3 scripts/gen/gen_jlink_w4.py <binary> <base_addr_hex> \
33 [--device <device_name>]
34 python3 scripts/gen/gen_jlink_w4.py firmware.bin 0x02000000 > flash.jlink
35
36The binary must be a flat raw image whose first byte maps to base_addr.
37Use arm-none-eabi-objcopy -O binary to produce one from an ELF.
38
39Note: pass -SelectEmuBySN <SN> to JLinkExe on the command line, NOT via
40the generated script. Placing SelectEmuBySN inside the commander script
41causes J-Link to fail subsequent halt commands on RA8D2 with SSD enabled.
42"""
43
44import struct
45import sys
46from pathlib import Path
47
48# Minimum positional argument count: <binary> <base_addr_hex>
49MIN_ARGS = 3
50
51
52def main() -> None:
53 """Emit the J-Link commander script for one binary at one base address.
54
55 Writes the script to stdout; the caller pipes it to JLinkExe. Exits 1 on
56 a usage error and returns None otherwise -- there is no partial-success
57 state, since the script is either fully emitted or not at all.
58 """
59 if len(sys.argv) < MIN_ARGS:
60 print(
61 f"Usage: {sys.argv[0]} <binary> <base_addr_hex> [--device DEV]",
62 file=sys.stderr,
63 )
64 sys.exit(1)
65
66 bin_file: str = sys.argv[1]
67 base: int = int(sys.argv[2], 16)
68 device: str = "R7KA8D2KF_CPU0"
69
70 i: int = 3
71 while i < len(sys.argv):
72 if sys.argv[i] == "--device" and i + 1 < len(sys.argv):
73 device = sys.argv[i + 1]
74 i += 2
75 else:
76 print(f"Unknown arg: {sys.argv[i]}", file=sys.stderr)
77 sys.exit(1)
78
79 with Path(bin_file).open("rb") as f:
80 data: bytes = f.read()
81
82 while len(data) % 4:
83 data += b"\xff"
84
85 initial_sp: int = struct.unpack_from("<I", data, 0)[0]
86 reset_handler: int = struct.unpack_from("<I", data, 4)[0] & 0xFFFFFFFE
87
88 print(f"device {device}")
89 print("si SWD")
90 print("speed 1000")
91 print("connect")
92 print("halt")
93 for idx in range(0, len(data), 4):
94 word: int = struct.unpack_from("<I", data, idx)[0]
95 print(f"w4 0x{base + idx:08X} 0x{word:08X}")
96
97 print(f"w4 0xE000EDF8 0x{initial_sp:08X}")
98 print("w4 0xE000EDF4 0x00010011")
99 print("w4 0xE000EDF8 0x01000000")
100 print("w4 0xE000EDF4 0x00010010")
101 print("w4 0xE000EDF8 0x00000000")
102 print("w4 0xE000EDF4 0x00010014")
103 print(f"w4 0xE000EDF8 0x{reset_handler:08X}")
104 print("w4 0xE000EDF4 0x0001000F")
105 print("g")
106 print("q")
107
108
109if __name__ == "__main__":
110 main()
void main(void)
The application entry point Reset_Handler hands control to.
Definition main.c:298