Skip to content

Commit 224b87a

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 bfa2863 commit 224b87a

File tree

2 files changed

+169
-0
lines changed

2 files changed

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

0 commit comments

Comments
 (0)