Skip to content

Commit 242c936

Browse files
RtkFPcaiyi_zhong
authored andcommitted
script: Add flash runner for rts5817
Add flash runner script to support west flash for rts5817 Signed-off-by: Darcy Lu <darcy_lu@realsil.com.cn>
1 parent 1fa08da commit 242c936

File tree

2 files changed

+175
-0
lines changed

2 files changed

+175
-0
lines changed

scripts/west_commands/runners/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ def _import_runner_module(runner_name):
5656
'renode',
5757
'renode-robot',
5858
'rfp',
59+
'rtsflash',
5960
'silabs_commander',
6061
'spi_burn',
6162
'stm32cubeprogrammer',
Lines changed: 174 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,174 @@
1+
# Copyright (c) 2024 Realtek Semiconductor, Inc.
2+
#
3+
# SPDX-License-Identifier: Apache-2.0
4+
5+
"""Runner for flashing with rtsflash."""
6+
7+
import subprocess
8+
import sys
9+
import time
10+
11+
import usb.core
12+
import usb.util
13+
14+
from runners.core import RunnerCaps, ZephyrBinaryRunner
15+
16+
RTS_STANDARD_REQUEST = 0x0
17+
18+
RTS_STD_GET_STATUS = 0x1A
19+
RTS_STD_SET_STATUS = 0x1B
20+
21+
RTS_STD_DOWNLOAD_ENABLE = 0x1
22+
RTS_STD_DOWNLOAD_DISABLE = 0x1
23+
24+
RTS_VENDOR_REQUEST = 0x40
25+
RTS_VREQ_XMEM_WRITE = 0x40
26+
RTS_VREQ_XMEM_READ = 0x41
27+
RTS_VREQ_SF_ERASE_SECTOR = 0x33
28+
29+
RTS_SET_FW_VERSION = 0x01
30+
RTS_DOWNLOAD_IMAGE = 0x03
31+
RTS_RESET_APP = 0x06
32+
RTS_GET_UPDATE_RESULT = 0x07
33+
RTS_RESET_IAP = 0x08
34+
35+
36+
class RtsUsb:
37+
def __init__(self, device=None):
38+
if not device:
39+
idvendor = 0x0BDA
40+
idproduct = 0x5817
41+
else:
42+
idvendor = int(device.split(':', 1)[0], 16)
43+
idproduct = int(device.split(':', 1)[1], 16)
44+
dev = usb.core.find(idVendor=idvendor, idProduct=idproduct)
45+
if not dev:
46+
raise RuntimeError("device not found")
47+
self.dev = dev
48+
self.mode = ""
49+
self.get_mode()
50+
51+
def __del__(self):
52+
usb.util.dispose_resources(self.dev)
53+
54+
def enable_download(self):
55+
if self.mode == "ROM":
56+
status = self.dev.ctrl_transfer(
57+
RTS_STANDARD_REQUEST | 0x80, RTS_STD_GET_STATUS, 0, 0, 1
58+
)
59+
if int.from_bytes(status, byteorder="little") == 0:
60+
self.dev.ctrl_transfer(RTS_STANDARD_REQUEST, RTS_STD_SET_STATUS, 1, 0, 0)
61+
62+
def xmem_write(self, addr, data):
63+
setup_value = addr & 0xFFFF
64+
setup_index = (addr >> 16) & 0xFFFF
65+
self.dev.ctrl_transfer(
66+
RTS_VENDOR_REQUEST, RTS_VREQ_XMEM_WRITE, setup_value, setup_index, data
67+
)
68+
69+
def xmem_read(self, addr):
70+
setup_value = addr & 0xFFFF
71+
setup_index = (addr >> 16) & 0xFFFF
72+
ret = self.dev.ctrl_transfer(
73+
RTS_VENDOR_REQUEST | 0x80, RTS_VREQ_XMEM_READ, setup_value, setup_index, 4
74+
)
75+
return int.from_bytes(ret, byteorder="little")
76+
77+
def get_mode(self):
78+
init_vector = self.xmem_read(0x401E2090)
79+
if init_vector == 0:
80+
self.mode = "ROM"
81+
elif init_vector == 0x01800000:
82+
self.mode = "IAP"
83+
else:
84+
raise ValueError("Unknown work mode")
85+
86+
87+
class RtsflashBinaryRunner(ZephyrBinaryRunner):
88+
"""Runner front-end for rtsflash."""
89+
90+
def __init__(self, cfg, dev_id, alt, img, exe='dfu-util'):
91+
super().__init__(cfg)
92+
self.dev_id = dev_id
93+
self.alt = alt
94+
self.img = img
95+
self.cmd = [exe, f'-d {dev_id}']
96+
try:
97+
self.list_pattern = f', alt={int(self.alt)},'
98+
except ValueError:
99+
self.list_pattern = f', name="{self.alt}",'
100+
self.reset = False
101+
102+
@classmethod
103+
def name(cls):
104+
return "rtsflash"
105+
106+
@classmethod
107+
def capabilities(cls):
108+
return RunnerCaps(commands={"flash"}, dev_id=True)
109+
110+
@classmethod
111+
def dev_id_help(cls) -> str:
112+
return 'USB VID:PID of the connected device.'
113+
114+
@classmethod
115+
def do_add_parser(cls, parser):
116+
parser.add_argument(
117+
"--alt", required=True, help="interface alternate setting number or name"
118+
)
119+
parser.add_argument("--pid", dest='dev_id', help=cls.dev_id_help())
120+
parser.add_argument("--img", help="binary to flash, default is --bin-file")
121+
parser.add_argument(
122+
'--dfu-util', default='dfu-util', help='dfu-util executable; defaults to "dfu-util"'
123+
)
124+
125+
@classmethod
126+
def do_create(cls, cfg, args):
127+
if args.img is None:
128+
args.img = cfg.bin_file
129+
130+
ret = RtsflashBinaryRunner(cfg, args.dev_id, args.alt, args.img, exe=args.dfu_util)
131+
132+
ret.ensure_device()
133+
return ret
134+
135+
def ensure_device(self):
136+
if not self.find_device():
137+
self.reset = True
138+
print('Please reset your board to switch to DFU mode...')
139+
while not self.find_device():
140+
time.sleep(0.1)
141+
142+
def find_device(self):
143+
cmd = list(self.cmd) + ['-l']
144+
output = self.check_output(cmd)
145+
output = output.decode(sys.getdefaultencoding())
146+
return self.list_pattern in output
147+
148+
def do_run(self, command, **kwargs):
149+
if not self.dev_id:
150+
raise RuntimeError(
151+
'Please specify a USB VID:PID with the -i/--dev-id or --pid command-line switch.'
152+
)
153+
154+
self.require(self.cmd[0])
155+
self.ensure_output('bin')
156+
157+
if not self.find_device():
158+
raise RuntimeError('device not found')
159+
160+
fpusb = RtsUsb(self.dev_id)
161+
162+
fpusb.enable_download()
163+
164+
try:
165+
self.check_call(['dfu-suffix', '-c', self.img])
166+
except subprocess.CalledProcessError:
167+
self.call(['dfu-suffix', '-a', self.img])
168+
169+
cmd = list(self.cmd)
170+
cmd.extend(['-a', self.alt, '-D', self.img])
171+
self.check_call(cmd)
172+
173+
if self.reset:
174+
print('Now reset your board again to switch back to runtime mode.')

0 commit comments

Comments
 (0)