Skip to content

Commit 9e43a5a

Browse files
committed
Move com port listing to after connection failure
Avoids a 2 second delay on Mac Also added comments reflecting newfound knowledge about why the minimum timeout value is set to 50 ms
1 parent 8f7579f commit 9e43a5a

File tree

1 file changed

+131
-134
lines changed

1 file changed

+131
-134
lines changed

tools/artemis/artemis_svl.py

Lines changed: 131 additions & 134 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,8 @@ def phase_set_baud(ser):
111111
# Target begins sending, then host reads 'len(baud_set_command)' bytes (incorrectly) and returns. While loop gives target time to finish transmitting
112112
# Target baud is high, host baud is low:
113113
# Target begins sending, host reads past the end of target transmission, then ready to go again. While loop not needed, but does not hurt
114-
114+
# ser.write(global_timeout.to_bytes(1,'big'))
115+
115116
verboseprint('Try #' + str(tri) + '. Result: ' + str(result))
116117
if(len(result) != len(baud_set_command)):
117118
print("Baud Set: lengths did not match")
@@ -146,179 +147,175 @@ def main():
146147
# Assuming worst case ~100 ms/page of flashing time, and allowing for the
147148
# image to be close to occupying full SRAM (256K) which is 128 pages.
148149

149-
# Check to see if the com port is available
150+
# Begin talking over com port
151+
print('Connecting over serial port {}...'.format(args.port), flush=True)
152+
153+
# Set a timeout
154+
global_timeout = 0.05 # tested as low as 0.03 on some machines - 50 ms works well, 30 ms works sometimes, this delay occurs between the USB-serial converter and when python can see it
155+
verboseprint('Using Serial timeout: ' + str(global_timeout))
156+
157+
# Now open the port for bootloading
150158
try:
151-
with serial.Serial(args.port, args.baud, timeout=0.05) as ser:
152-
pass
153-
except:
159+
with serial.Serial(args.port, args.baud, timeout=global_timeout) as ser:
154160

155-
# Show a list of com ports and recommend one
156-
devices = list_ports.comports()
161+
# DTR is driven low when serial port open. DTR has now pulled RST low causing board reset.
162+
# If we do not set DTR high again, the Ambiq SBL will not activate, but the SparkFun bootloader will.
157163

158-
# First check to see if user has the given port open
159-
for dev in devices:
160-
if(dev.device.upper() == args.port.upper()):
161-
print(dev.device + " is currently open. Please close any other terminal programs that may be using " +
162-
dev.device + " and try again.")
164+
if(phase_set_baud(ser) != 0):
165+
print('Failed baud set phase')
163166
exit()
164167

165-
# otherwise, give user a list of possible com ports
166-
print(args.port.upper() +
167-
" not found but we detected the following serial ports:")
168-
for dev in devices:
169-
if 'CH340' in dev.description:
170-
print(
171-
dev.description + ": Likely an Arduino or derivative. Try " + dev.device + ".")
172-
elif 'FTDI' in dev.description:
173-
print(
174-
dev.description + ": Likely an Arduino or derivative. Try " + dev.device + ".")
175-
elif 'USB Serial Device' in dev.description:
176-
print(
177-
dev.description + ": Possibly an Arduino or derivative.")
178-
else:
179-
print(dev.description)
168+
print('Connected!')
169+
print('Bootloading...')
180170

181-
exit()
171+
# Wait for incoming BL_COMMAND_ANNOUNCE
172+
i = 0
173+
response = ''
174+
while len(response) == 0:
175+
i = i + 1
176+
if(i == 30):
177+
print("No announcement from Artemis bootloader")
178+
exit()
182179

183-
# Begin talking over com port
184-
print('Connecting over serial port {}...'.format(args.port), flush=True)
180+
response = ser.read()
185181

186-
# # compute an acceptable timeout for the given baud rate
187-
# global_timeout = 10*(25)/args.baud
188-
global_timeout = 0.05
189-
verboseprint('Using Serial timeout: ' + str(global_timeout))
182+
if(len(response) > 0):
183+
if(ord(response) == BL_COMMAND_ANNOUNCE):
184+
# Respond with 'AOK'
185+
# values = bytearray([6])
186+
ser.write(BL_COMMAND_AOK.to_bytes(1, byteorder='big'))
190187

191-
# Now open the port for bootloading
192-
with serial.Serial(args.port, args.baud, timeout=global_timeout) as ser:
188+
verboseprint("Bootload response received")
189+
break
190+
else:
191+
verboseprint("Unkown response: " + str(ord(response)))
192+
response = ''
193193

194-
# DTR is driven low when serial port open. DTR has now pulled RST low causing board reset.
195-
# If we do not set DTR high again, the Ambiq SBL will not activate, but the SparkFun bootloader will.
194+
# Wait for incoming char indicating bootloader version
195+
i = 0
196+
response = ''
197+
while len(response) == 0:
198+
i = i + 1
199+
if(i == 10):
200+
print("No version from Artemis bootloader")
201+
exit()
196202

197-
if(phase_set_baud(ser) != 0):
198-
exit()
203+
response = ser.read()
199204

200-
print('Connected!')
201-
print('Bootloading...')
205+
verboseprint("Bootloader version: " + str(ord(response)))
202206

203-
# Wait for incoming BL_COMMAND_ANNOUNCE
204-
i = 0
205-
response = ''
206-
while len(response) == 0:
207-
i = i + 1
208-
if(i == 30):
209-
print("No announcement from Artemis bootloader")
210-
exit()
207+
# Read the binary file from the command line.
208+
with open(args.binfile, mode='rb') as binfile:
209+
application = binfile.read()
210+
# Gather the important binary metadata.
211+
totalLen = len(application)
211212

212-
response = ser.read()
213+
verboseprint("Length to send: " + str(totalLen))
213214

214-
if(len(response) > 0):
215-
if(ord(response) == BL_COMMAND_ANNOUNCE):
216-
# Respond with 'AOK'
217-
# values = bytearray([6])
218-
ser.write(BL_COMMAND_AOK.to_bytes(1, byteorder='big'))
215+
start = 0
216+
end = start + 512*4
219217

220-
verboseprint("Bootload response received")
221-
break
222-
else:
223-
verboseprint("Unkown response: " + str(ord(response)))
224-
response = ''
225-
226-
# Wait for incoming char indicating bootloader version
227-
i = 0
228-
response = ''
229-
while len(response) == 0:
230-
i = i + 1
231-
if(i == 10):
232-
print("No version from Artemis bootloader")
233-
exit()
218+
# Loop until we have sent the entire file
219+
while 1:
234220

235-
response = ser.read()
221+
# Calc CRC for this chunk
222+
bytes_to_send = end - start
223+
words_to_send = bytes_to_send / 4
224+
myCRC32 = 0
225+
i = 0
226+
while i < words_to_send:
227+
partialStart = int(start + (i * (bytes_to_send/words_to_send)))
228+
partialEnd = int(
229+
end - ((words_to_send - 1 - i) * (bytes_to_send/words_to_send)))
236230

237-
verboseprint("Bootloader version: " + str(ord(response)))
231+
myCRC32 = myCRC32 + \
232+
int.from_bytes(
233+
application[partialStart:partialEnd], 'little')
238234

239-
# Read the binary file from the command line.
240-
with open(args.binfile, mode='rb') as binfile:
241-
application = binfile.read()
242-
# Gather the important binary metadata.
243-
totalLen = len(application)
235+
i = i + 1
244236

245-
verboseprint("Length to send: " + str(totalLen))
237+
myCRC32 = myCRC32 % 4294967296 # Trim any larger than 32-bit values
246238

247-
start = 0
248-
end = start + 512*4
239+
# Tell the target we are ready with new data
240+
ser.write(BL_COMMAND_COMPUTER_READY.to_bytes(1, byteorder='big'))
249241

250-
# Loop until we have sent the entire file
251-
while 1:
242+
# Wait for incoming BL_COMMAND_NEXT_FRAME indicating the sending of next frame
243+
i = 0
244+
response = ''
245+
while len(response) == 0:
246+
i = i + 1
247+
if(i == 10):
248+
print("Bootloader did not request next frame")
249+
exit()
252250

253-
# Calc CRC for this chunk
254-
bytes_to_send = end - start
255-
words_to_send = bytes_to_send / 4
256-
myCRC32 = 0
257-
i = 0
258-
while i < words_to_send:
259-
partialStart = int(start + (i * (bytes_to_send/words_to_send)))
260-
partialEnd = int(
261-
end - ((words_to_send - 1 - i) * (bytes_to_send/words_to_send)))
251+
response = ser.read()
262252

263-
myCRC32 = myCRC32 + \
264-
int.from_bytes(
265-
application[partialStart:partialEnd], 'little')
253+
if ord(response) == BL_COMMAND_NEXT_FRAME:
254+
verboseprint("Sending next frame: " +
255+
str(end - start) + " bytes")
266256

267-
i = i + 1
257+
if(start == totalLen):
258+
# We're done!
259+
print("Upload complete")
268260

269-
myCRC32 = myCRC32 % 4294967296 # Trim any larger than 32-bit values
261+
# Send size of this frame - special command
262+
ser.write(BL_COMMAND_ALL_DONE.to_bytes(2, byteorder='big'))
270263

271-
# Tell the target we are ready with new data
272-
ser.write(BL_COMMAND_COMPUTER_READY.to_bytes(1, byteorder='big'))
264+
exit()
273265

274-
# Wait for incoming BL_COMMAND_NEXT_FRAME indicating the sending of next frame
275-
i = 0
276-
response = ''
277-
while len(response) == 0:
278-
i = i + 1
279-
if(i == 10):
280-
print("Bootloader did not request next frame")
281-
exit()
266+
# Send size of this frame
267+
bytes_to_send = end - start
268+
ser.write(bytes_to_send.to_bytes(2, byteorder='big'))
282269

283-
response = ser.read()
270+
# Send start address of this frame
271+
ser.write(start.to_bytes(4, byteorder='big'))
284272

285-
if ord(response) == BL_COMMAND_NEXT_FRAME:
286-
verboseprint("Sending next frame: " +
287-
str(end - start) + " bytes")
273+
# Send our CRC
274+
ser.write(myCRC32.to_bytes(4, byteorder='big'))
288275

289-
if(start == totalLen):
290-
# We're done!
291-
print("Upload complete")
276+
# Send page of data
277+
ser.write(application[start:end])
292278

293-
# Send size of this frame - special command
294-
ser.write(BL_COMMAND_ALL_DONE.to_bytes(2, byteorder='big'))
279+
# Move the pointers foward
280+
start = end
281+
end = end + 512*4
295282

283+
if end > totalLen:
284+
end = totalLen
285+
else:
286+
print("Unknown BL response")
296287
exit()
297288

298-
# Send size of this frame
299-
bytes_to_send = end - start
300-
ser.write(bytes_to_send.to_bytes(2, byteorder='big'))
301-
302-
# Send start address of this frame
303-
ser.write(start.to_bytes(4, byteorder='big'))
304-
305-
# Send our CRC
306-
ser.write(myCRC32.to_bytes(4, byteorder='big'))
289+
exit()
307290

308-
# Send page of data
309-
ser.write(application[start:end])
291+
except:
292+
# Show a list of com ports and recommend one
293+
devices = list_ports.comports()
310294

311-
# Move the pointers foward
312-
start = end
313-
end = end + 512*4
295+
# First check to see if user has the given port open
296+
for dev in devices:
297+
if(dev.device.upper() == args.port.upper()):
298+
print(dev.device + " is currently open. Please close any other terminal programs that may be using " +
299+
dev.device + " and try again.")
300+
exit()
314301

315-
if end > totalLen:
316-
end = totalLen
302+
# otherwise, give user a list of possible com ports
303+
print(args.port.upper() +
304+
" not found but we detected the following serial ports:")
305+
for dev in devices:
306+
if 'CH340' in dev.description:
307+
print(
308+
dev.description + ": Likely an Arduino or derivative. Try " + dev.device + ".")
309+
elif 'FTDI' in dev.description:
310+
print(
311+
dev.description + ": Likely an Arduino or derivative. Try " + dev.device + ".")
312+
elif 'USB Serial Device' in dev.description:
313+
print(
314+
dev.description + ": Possibly an Arduino or derivative.")
317315
else:
318-
print("Unknown BL response")
319-
exit()
316+
print(dev.description)
320317

321-
exit()
318+
exit()
322319

323320

324321
# ******************************************************************************

0 commit comments

Comments
 (0)