Skip to content

Commit 52e575c

Browse files
authored
Merge pull request #298 from Infineon/feature/DESMAKERS-4040-improve-user-experience-xmc4arduino-flasher-script
Fix: automatically select default port and remove mojibake
2 parents 7b6753e + c008480 commit 52e575c

File tree

3 files changed

+61
-18
lines changed

3 files changed

+61
-18
lines changed

platform.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -147,12 +147,12 @@ recipe.size.regex.data=^(?:\.data|\.VENEER_Code|\.ram_code|\.bss|\.no_init|\Stac
147147
# ----------------
148148
tools.xmcflasher.path={runtime.platform.path}/tools
149149
tools.xmcflasher.cmd.path={path}/xmc-flasher.py
150-
tools.xmcflasher.erase.params=-d XMC{build.board.version}-{build.board.v} -p {serial.port}
150+
tools.xmcflasher.erase.params=-d XMC{build.board.version}-{build.board.v} -p {upload.port.address}
151151
tools.xmcflasher.erase.pattern=python3 {cmd.path} erase {erase.params}
152152
tools.xmcflasher.erase.pattern.windows=python {cmd.path} erase {erase.params}
153153
tools.xmcflasher.upload.protocol=
154154
tools.xmcflasher.upload.params.verbose=--verbose
155155
tools.xmcflasher.upload.params.quiet=
156-
tools.xmcflasher.upload.params=-d XMC{build.board.version}-{build.board.v} -p {serial.port} -f {build.path}/{build.project_name}.hex {upload.verbose}
156+
tools.xmcflasher.upload.params=-d XMC{build.board.version}-{build.board.v} -p {upload.port.address} -f {build.path}/{build.project_name}.hex {upload.verbose}
157157
tools.xmcflasher.upload.pattern=python3 {cmd.path} upload {upload.params}
158158
tools.xmcflasher.upload.pattern.windows=python {cmd.path} upload {upload.params}

tools/xmc-flasher.py

Lines changed: 55 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,17 @@ def set_environment():
3737
elif sys.platform == 'darwin':
3838
jlinkexe = 'JLinkExe'
3939

40-
def discover_devices():
40+
def discover_jlink_devices():
4141
ports = comports()
4242
port_sn_list = []
4343
for p in ports:
44-
port_sn_list.append((p.device, p.serial_number))
44+
if "JLink" in p.description:
45+
port_sn_list.append((p.device, p.serial_number))
4546

4647
return port_sn_list
4748

4849
def get_device_serial_number(port):
49-
port_sn_list = discover_devices()
50+
port_sn_list = discover_jlink_devices()
5051
for device in port_sn_list:
5152
if device[0] == port and device[0] != None:
5253
return device[1]
@@ -81,6 +82,16 @@ def remove_console_output_file(console_output_file):
8182
if os.path.exists(console_output_file):
8283
os.remove(console_output_file)
8384

85+
def remove_backspaces(input_str):
86+
result = []
87+
for char in input_str:
88+
if char == '\b':
89+
if result:
90+
result.pop()
91+
else:
92+
result.append(char)
93+
return ''.join(result)
94+
8495
def jlink_commander(device, serial_num, cmd_file, console_output=False):
8596
jlink_cmd = [jlinkexe, '-autoconnect', '1','-exitonerror', '1', '-nogui', '1', '-device', device, '-selectemubysn', serial_num, '-if', 'swd', '-speed', '4000', '-commandfile', cmd_file]
8697

@@ -92,10 +103,10 @@ def jlink_commander(device, serial_num, cmd_file, console_output=False):
92103
if console_output is True:
93104
out, err = jlink_proc.communicate()
94105
with open(console_out, 'w') as f:
95-
f.write(out)
106+
f.write(remove_backspaces(out))
96107
else:
97108
for line in jlink_proc.stdout:
98-
print(line, end='')
109+
print(remove_backspaces(line), end='')
99110
jlink_proc.wait()
100111
except:
101112
raise Exception("jlink error")
@@ -146,6 +157,12 @@ def get_mem_contents(addr, bytes, device, port):
146157
def read_master_data():
147158
return xmc_master_data
148159

160+
def find_device_by_value(value):
161+
master_data = read_master_data()
162+
for device, config in master_data.items():
163+
if config["IDCHIP"]["value"] == value:
164+
return device
165+
return None
149166

150167
def check_device(device, port):
151168

@@ -156,12 +173,14 @@ def check_device(device, port):
156173
device_value_masked = f'{device_value_masked:x}'
157174
device_value_masked = device_value_masked.zfill(int(master_data[device]['IDCHIP']['size'])*2)
158175

159-
print(f"Device is: {device.split('-')[0]}.")
160-
161-
#compare with stored master data
162-
if not device_value_masked == master_data[device]['IDCHIP']['value']:
163-
raise Exception("Device connected does not match the selected device to flash")
176+
print(f"Selected Device is: {device}.")
164177

178+
real_device = find_device_by_value(device_value_masked)
179+
#compare with stored master data
180+
if not real_device == device:
181+
if real_device != None:
182+
print(f"Connected Device is: {real_device}.")
183+
raise Exception(f"Device connected on port {port} does not match the selected device to flash")
165184

166185
def check_mem(device, port):
167186

@@ -196,7 +215,20 @@ def check_mem(device, port):
196215
#compare with stored master data
197216
if not device_value_masked.upper() == master_data[device]['FLASH0_ID']['value']:
198217
raise Exception("Memory size of device connected does not match that of the selected device to flash")
199-
218+
219+
def get_default_port(port):
220+
serial_num = get_device_serial_number(port)
221+
if serial_num == None or port == None:
222+
port_sn_list = discover_jlink_devices()
223+
for port_sn in port_sn_list:
224+
if port_sn[1] != None:
225+
real_port = port_sn[0]
226+
print(f"Device found on port: {real_port}, not on the selected port: {port}.")
227+
print(f"Automatically selecting port {real_port}...")
228+
return real_port
229+
else:
230+
return port
231+
200232

201233
def upload(device, port, binfile, enable_jlink_log):
202234
serial_num = get_device_serial_number(port)
@@ -236,6 +268,10 @@ def parser_upload_func(args):
236268
else:
237269
print("Upload failed.")
238270
remove_console_output_file(console_out)
271+
# Log if the port value has changed
272+
if args.port != original_port:
273+
print(f"Please select port {args.port} for using the Serial Monitor or Plotter.")
274+
239275

240276
def parser_erase_func(args):
241277
erase(args.device, args.port)
@@ -258,7 +294,7 @@ def __call__(self, parser, namespace, values, option_string, **kwargs):
258294
parser_upload = subparser.add_parser('upload', description='Upload binary command')
259295
required_upload = parser_upload.add_argument_group('required arguments')
260296
required_upload.add_argument('-d','--device', type=str, help='jlink device name', required=True)
261-
required_upload.add_argument('-p','--port', type=str, help='serial port', required=True)
297+
required_upload.add_argument('-p','--port', type=str, nargs='?', const='', help='serial port')
262298
required_upload.add_argument('-f','--binfile', type=str, help='binary file to upload', required=True)
263299
required_upload.add_argument('--verbose', action='store_true', help='Enable verbose logging')
264300
parser_upload.set_defaults(func=parser_upload_func)
@@ -280,6 +316,13 @@ def __call__(self, parser, namespace, values, option_string, **kwargs):
280316
sys.tracebacklimit = None # Enable full traceback
281317
else:
282318
sys.tracebacklimit = 0 # Disable traceback
319+
320+
# Store the original port value
321+
original_port = args.port
322+
323+
# Select default port if not provided/ or device not found on the selected port
324+
args.port = get_default_port(args.port)
325+
283326
# Parser call
284327
args.func(args)
285328

tools/xmc_data.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,8 @@
4747
"IDCHIP":{
4848
"addr":"40010004",
4949
"size":"4",
50-
"value":"00014000",
51-
"mask":"FFFFF000"
50+
"value":"00014010",
51+
"mask":"000FFFF0"
5252
},
5353
"FLSIZE":{
5454
"addr":"40000404",
@@ -61,8 +61,8 @@
6161
"IDCHIP":{
6262
"addr":"40010004",
6363
"size":"4",
64-
"value":"00014000",
65-
"mask":"FFFFF000"
64+
"value":"00014040",
65+
"mask":"000FFFF0"
6666
},
6767
"FLSIZE":{
6868
"addr":"40000404",

0 commit comments

Comments
 (0)