1010TODO:
1111
1212Push user to upgrade bootloader as needed
13+ Bootloader from CLI:
14+ ambiq_bin2board.exe --bin "artemis_svl.bin" --load-address-blob 0x20000 --magic-num 0xCB --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b 115200 -port "COM3" -r 2 -v
15+
16+ ambiq_bin2board.exe --bin "artemis_svl.bin" --load-address-blob 0x20000 --magic-num 0xCB --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b 115200 -port "COM3" -r 2 -v
1317
1418"""
1519from typing import Iterator , Tuple
1620from serial .tools .list_ports import comports
17- from PyQt5 .QtCore import QSettings , QProcess
21+ from PyQt5 .QtCore import QSettings , QProcess , QTimer
1822from PyQt5 .QtWidgets import QWidget , QLabel , QComboBox , QGridLayout , \
19- QPushButton , QApplication , QLineEdit , QFileDialog
20- from PyQt5 .QtGui import QCloseEvent
21-
22- # import artemis_svl
23+ QPushButton , QApplication , QLineEdit , QFileDialog , QPlainTextEdit
24+ from PyQt5 .QtGui import QCloseEvent , QTextCursor
2325
2426# Setting constants
2527SETTING_PORT_NAME = 'port_name'
2628SETTING_FILE_LOCATION = 'message'
2729SETTING_BAUD_RATE = '921600'
2830
29- progressCount = 1
30-
3131guiVersion = 'v1.0'
3232
3333
@@ -69,7 +69,7 @@ def __init__(self, parent: QWidget = None) -> None:
6969 self .refresh_btn .pressed .connect (self .on_refresh_btn_pressed )
7070
7171 # Baudrate Combobox
72- self .baud_label = QLabel (self .tr ('Baud:' ))
72+ self .baud_label = QLabel (self .tr ('Baud Rate :' ))
7373 self .baud_combobox = QComboBox ()
7474 self .baud_label .setBuddy (self .baud_combobox )
7575 self .update_baud_rates ()
@@ -78,10 +78,24 @@ def __init__(self, parent: QWidget = None) -> None:
7878 self .upload_btn = QPushButton (self .tr ('Upload' ))
7979 self .upload_btn .pressed .connect (self .on_upload_btn_pressed )
8080
81+ # Upload Button
82+ self .updateBootloader_btn = QPushButton (self .tr ('Update Bootloader' ))
83+ self .updateBootloader_btn .pressed .connect (
84+ self .on_update_bootloader_btn_pressed )
85+
8186 # Status bar
8287 self .status_label = QLabel (self .tr ('Status:' ))
8388 self .status = QLabel (self .tr (' ' ))
8489
90+ # Messages Bar
91+ self .messages_label = QLabel (self .tr ('Status / Warnings:' ))
92+
93+ # Messages Window
94+ self .messages = QPlainTextEdit ()
95+ # Attempting to reduce window size
96+ #self.messages.setMinimumSize(1, 2)
97+ #self.messages.resize(1, 2)
98+
8599 # Arrange Layout
86100 layout = QGridLayout ()
87101 layout .addWidget (self .msg_label , 0 , 0 )
@@ -94,14 +108,30 @@ def __init__(self, parent: QWidget = None) -> None:
94108
95109 layout .addWidget (self .baud_label , 2 , 0 )
96110 layout .addWidget (self .baud_combobox , 2 , 1 )
97- layout .addWidget (self .upload_btn , 3 , 2 )
98111
99- layout .addWidget (self .status_label , 3 , 0 )
100- layout .addWidget (self .status , 3 , 1 )
112+ #layout.addWidget(self.status_label, 3, 0)
113+ #layout.addWidget(self.status, 3, 1)
114+
115+ layout .addWidget (self .messages_label , 3 , 0 )
116+ layout .addWidget (self .messages , 4 , 0 , 4 , 3 )
117+
118+ layout .addWidget (self .upload_btn , 15 , 2 )
119+ layout .addWidget (self .updateBootloader_btn , 15 , 1 )
120+
101121 self .setLayout (layout )
102122
103123 self ._load_settings ()
104124
125+ # Make the text edit window read-only
126+ self .messages .setReadOnly (True )
127+ self .messages .clear () # Clear the message window
128+
129+ def addMessage (self , msg : str ) -> None :
130+ self .messages .moveCursor (QTextCursor .End )
131+ self .messages .ensureCursorVisible ()
132+ self .messages .appendPlainText (msg )
133+ self .messages .ensureCursorVisible ()
134+
105135 def _load_settings (self ) -> None :
106136 """Load settings on startup."""
107137 settings = QSettings ()
@@ -139,11 +169,26 @@ def show_error_message(self, msg: str) -> None:
139169 def update_com_ports (self ) -> None :
140170 """Update COM Port list in GUI."""
141171 self .port_combobox .clear ()
172+
173+ index = 0
174+ indexOfCH340 = - 1
142175 for name , device in gen_serial_ports ():
143176 self .port_combobox .addItem (name , device )
177+ if ("CH340" in name ):
178+ if (indexOfCH340 == - 1 ): # Select the first available
179+ indexOfCH340 = index
180+ #print("CH340 found at index " + str(indexOfCH340))
181+ index = index + 1
182+
183+ # If we have no previous settings, and CH340 is in the list, auto-select it
184+ if indexOfCH340 > - 1 :
185+ settings = QSettings ()
186+ port_name = settings .value (SETTING_PORT_NAME )
187+ if port_name is not None :
188+ self .port_combobox .setCurrentIndex (indexOfCH340 )
144189
145190 def update_baud_rates (self ) -> None :
146- """Update COM Port list in GUI."""
191+ """Update baud rate list in GUI."""
147192 self .baud_combobox .addItem ("921600" , 921600 )
148193 self .baud_combobox .addItem ("460800" , 460800 )
149194 self .baud_combobox .addItem ("115200" , 115200 )
@@ -167,6 +212,7 @@ def closeEvent(self, event: QCloseEvent) -> None:
167212
168213 def on_refresh_btn_pressed (self ) -> None :
169214 self .update_com_ports ()
215+ self .addMessage ("Ports Refreshed" )
170216
171217 def on_upload_btn_pressed (self ) -> None :
172218 """Check if port is available"""
@@ -176,7 +222,7 @@ def on_upload_btn_pressed(self) -> None:
176222 if (p .device == self .port ):
177223 portAvailable = True
178224 if (portAvailable == False ):
179- self .status . setText ("Port No Longer Available" )
225+ self .addMessage ("Port No Longer Available" )
180226 return
181227
182228 """Check if file exists"""
@@ -188,46 +234,62 @@ def on_upload_btn_pressed(self) -> None:
188234 fileExists = False
189235 finally :
190236 if (fileExists == False ):
191- self .status . setText ("File Not Found" )
237+ self .addMessage ("File Not Found" )
192238 return
193239 f .close ()
194240
195- global progressCount
196- progressCount = 0
241+ self .addMessage ("Uploading" )
242+
243+ self .process = QProcess ()
244+ self .process .readyReadStandardError .connect (
245+ self .onReadyReadStandardError )
246+ self .process .readyReadStandardOutput .connect (
247+ self .onReadyReadStandardOutput )
248+
249+ commandString = "tools/artemis_svl.exe " + \
250+ str (self .port ) + " -f\" " + self .fileLocation_lineedit .text () + \
251+ "\" " + " -b" + str (self .baudRate )
252+ print (commandString )
253+ self .process .start (commandString )
254+
255+ def on_update_bootloader_btn_pressed (self ) -> None :
256+ """Check if port is available"""
257+ portAvailable = False
258+ ports = comports ()
259+ for p in ports :
260+ if (p .device == self .port ):
261+ portAvailable = True
262+ if (portAvailable == False ):
263+ self .addMessage ("Port No Longer Available" )
264+ return
197265
198- self .status . setText ( "Uploading " )
266+ self .addMessage ( "Updating bootloader " )
199267
200268 self .process = QProcess ()
201269 self .process .readyReadStandardError .connect (
202270 self .onReadyReadStandardError )
203271 self .process .readyReadStandardOutput .connect (
204272 self .onReadyReadStandardOutput )
205273
206- self .process .start ("artemis_svl .exe " + str (self .port ) +
207- " -f \" " + self . fileLocation_lineedit . text () + " \" " + " -b" + str ( self . baudRate ) )
274+ self .process .start ("tools/ambiq_bin2board .exe --bin tools/artemis_svl.bin --load-address-blob 0x20000 --magic-num 0xCB --version 0x0 --load-address-wired 0xC000 -i 6 --options 0x1 -b 115200 -port " + str (self .port ) +
275+ " -r 2 -v" )
208276
209277 def onReadyReadStandardError (self ):
210278 error = self .process .readAllStandardError ().data ().decode ()
211279 # print(error)
212- self .status . setText (error )
280+ self .addMessage (error )
213281
214282 def onReadyReadStandardOutput (self ):
215283 """Parse the output from the process. Update our status as we go."""
216284 result = self .process .readAllStandardOutput ().data ().decode ()
217285 # print(result)
286+ self .addMessage (result )
218287 if ("complete" in result ):
219- self .status . setText ("Complete" )
288+ self .addMessage ("Complete" )
220289 elif ("failed" in result ):
221- self .status . setText ("Upload Failed" )
290+ self .addMessage ("Upload Failed" )
222291 elif ("open" in result ):
223- self .status .setText ("Port In Use / Please Close" )
224- else : # The '#' is displayed 50 times until completion
225- global progressCount
226- progressCount = progressCount + result .count ("#" )
227- # print(progressCount)
228- for i in range (int (progressCount / 3 )):
229- current = self .status .text () + "."
230- self .status .setText (current )
292+ self .addMessage ("Port In Use / Please Close" )
231293
232294 def on_browse_btn_pressed (self ) -> None :
233295 """Open dialog to select bin file."""
@@ -246,7 +308,7 @@ def on_browse_btn_pressed(self) -> None:
246308 import sys
247309 app = QApplication ([])
248310 app .setOrganizationName ('SparkFun' )
249- app .setApplicationName ('Artemis Firmware Uploader' )
311+ app .setApplicationName ('Artemis Firmware Uploader ' + guiVersion )
250312 w = RemoteWidget ()
251313 w .show ()
252314 sys .exit (app .exec_ ())
0 commit comments