1313
1414Pyinstaller:
1515Windows:
16- pyinstaller --onefile --clean --noconsole --distpath=./Windows_exe --icon=RTK.ico --add-binary="RTK_Surveyor.ino.partitions .bin;." --add-binary="RTK_Surveyor.ino.bootloader.bin;." --add-binary="boot_app0.bin;." --add-binary="RTK.png;." RTK_Firmware_Uploader_GUI.py
16+ pyinstaller --onefile --clean --noconsole --distpath=./Windows_exe --icon=RTK.ico --add-binary="RTK_Surveyor_Partitions_4MB.bin;." --add-binary="RTK_Surveyor_Partitions_16MB .bin;." --add-binary="RTK_Surveyor.ino.bootloader.bin;." --add-binary="boot_app0.bin;." --add-binary="RTK.png;." RTK_Firmware_Uploader_GUI.py
1717Linux:
18- pyinstaller --onefile --clean --noconsole --distpath=./Linux_exe --icon=RTK.ico --add-binary="RTK_Surveyor.ino.partitions .bin:." --add-binary="RTK_Surveyor.ino.bootloader.bin:." --add-binary="boot_app0.bin:." --add-binary="RTK.png:." RTK_Firmware_Uploader_GUI.py
18+ pyinstaller --onefile --clean --noconsole --distpath=./Linux_exe --icon=RTK.ico --add-binary="RTK_Surveyor_Partitions_4MB.bin:." --add-binary="RTK_Surveyor_Partitions_16MB .bin:." --add-binary="RTK_Surveyor.ino.bootloader.bin:." --add-binary="boot_app0.bin:." --add-binary="RTK.png:." RTK_Firmware_Uploader_GUI.py
1919
2020Pyinstaller needs:
2121RTK_Firmware_Uploader_GUI.py (this file!)
2222RTK.ico (icon file for the .exe)
2323RTK.png (icon for the GUI widget)
2424esptool.py (v3.3, copied from https://github.com/espressif/esptool/releases/tag/v3.3)
25- RTK_Surveyor.ino.partitions.bin
25+ RTK_Surveyor_Partitions_4MB.bin
26+ RTK_Surveyor_Partitions_16MB.bin
2627RTK_Surveyor.ino.bootloader.bin
2728boot_app0.bin
2829
5556# Setting constants
5657SETTING_PORT_NAME = 'port_name'
5758SETTING_FILE_LOCATION = 'file_location'
58- SETTING_PARTITION_LOCATION = 'partition_location'
59+ # SETTING_PARTITION_LOCATION = 'partition_location'
5960SETTING_BAUD_RATE = 'baud'
6061
6162guiVersion = 'v1.3'
@@ -74,9 +75,10 @@ def resource_path(relative_path):
7475class messageRedirect (QObject ):
7576 """Wrap a class around a QPlainTextEdit so we can redirect stdout and stderr to it"""
7677
77- def __init__ (self , edit , out = None ) -> None :
78+ def __init__ (self , edit , out = None , flashSize = None ) -> None :
7879 self .edit = edit
7980 self .out = out
81+ self .flashSize = flashSize
8082
8183 def write (self , msg ) -> None :
8284 if msg .startswith ("\r " ):
@@ -87,9 +89,20 @@ def write(self, msg) -> None:
8789 self .edit .insertPlainText (msg )
8890 self .edit .ensureCursorVisible ()
8991 self .edit .repaint ()
92+ QApplication .processEvents () # This prevents the circle of doom...
93+
9094 if self .out : # Echo to out (stdout) too if desired
9195 self .out .write (msg )
92- QApplication .processEvents ()
96+
97+ if self .flashSize :
98+ if msg .find ("Detected flash size: 4MB" ) >= 0 :
99+ self .flashSize [0 ] = 4
100+ elif msg .find ("Detected flash size: 8MB" ) >= 0 :
101+ self .flashSize [0 ] = 8
102+ elif msg .find ("Detected flash size: 16MB" ) >= 0 :
103+ self .flashSize [0 ] = 16
104+ elif msg .find ("Detected flash size: " ) >= 0 :
105+ self .flashSize [0 ] = 0
93106
94107 def flush (self ) -> None :
95108 None
@@ -105,6 +118,8 @@ class MainWidget(QWidget):
105118 def __init__ (self , parent : QWidget = None ) -> None :
106119 super ().__init__ (parent )
107120
121+ self .flashSize = [0 ] # flashSize needs to be mutable. Use a single element list
122+
108123 # File location line edit
109124 self .file_label = QLabel (self .tr ('Firmware File:' ))
110125 self .fileLocation_lineedit = QLineEdit ()
@@ -117,17 +132,17 @@ def __init__(self, parent: QWidget = None) -> None:
117132 self .browse_btn .setEnabled (True )
118133 self .browse_btn .pressed .connect (self .on_browse_btn_pressed )
119134
120- # Partition file location line edit
121- self .partition_label = QLabel (self .tr ('Partition File:' ))
122- self .partitionFileLocation_lineedit = QLineEdit ()
123- self .partition_label .setBuddy (self .partitionFileLocation_lineedit )
124- self .partitionFileLocation_lineedit .setEnabled (False )
125- self .partitionFileLocation_lineedit .returnPressed .connect (self .on_partition_browse_btn_pressed )
135+ # # Partition file location line edit
136+ # self.partition_label = QLabel(self.tr('Partition File:'))
137+ # self.partitionFileLocation_lineedit = QLineEdit()
138+ # self.partition_label.setBuddy(self.partitionFileLocation_lineedit)
139+ # self.partitionFileLocation_lineedit.setEnabled(False)
140+ # self.partitionFileLocation_lineedit.returnPressed.connect(self.on_partition_browse_btn_pressed)
126141
127- # Browse for new file button
128- self .partition_browse_btn = QPushButton (self .tr ('Browse' ))
129- self .partition_browse_btn .setEnabled (True )
130- self .partition_browse_btn .pressed .connect (self .on_partition_browse_btn_pressed )
142+ # # Browse for new file button
143+ # self.partition_browse_btn = QPushButton(self.tr('Browse'))
144+ # self.partition_browse_btn.setEnabled(True)
145+ # self.partition_browse_btn.pressed.connect(self.on_partition_browse_btn_pressed)
131146
132147 # Port Combobox
133148 self .port_label = QLabel (self .tr ('COM Port:' ))
@@ -167,20 +182,20 @@ def __init__(self, parent: QWidget = None) -> None:
167182 layout .addWidget (self .fileLocation_lineedit , 1 , 1 )
168183 layout .addWidget (self .browse_btn , 1 , 2 )
169184
170- layout .addWidget (self .partition_label , 2 , 0 )
171- layout .addWidget (self .partitionFileLocation_lineedit , 2 , 1 )
172- layout .addWidget (self .partition_browse_btn , 2 , 2 )
185+ # layout.addWidget(self.partition_label, 2, 0)
186+ # layout.addWidget(self.partitionFileLocation_lineedit, 2, 1)
187+ # layout.addWidget(self.partition_browse_btn, 2, 2)
173188
174- layout .addWidget (self .port_label , 3 , 0 )
175- layout .addWidget (self .port_combobox , 3 , 1 )
176- layout .addWidget (self .refresh_btn , 3 , 2 )
189+ layout .addWidget (self .port_label , 2 , 0 )
190+ layout .addWidget (self .port_combobox , 2 , 1 )
191+ layout .addWidget (self .refresh_btn , 2 , 2 )
177192
178- layout .addWidget (self .baud_label , 4 , 0 )
179- layout .addWidget (self .baud_combobox , 4 , 1 )
180- layout .addWidget (self .upload_btn , 4 , 2 )
193+ layout .addWidget (self .baud_label , 3 , 0 )
194+ layout .addWidget (self .baud_combobox , 3 , 1 )
195+ layout .addWidget (self .upload_btn , 3 , 2 )
181196
182- layout .addWidget (self .messages_label , 5 , 0 )
183- layout .addWidget (self .messageBox , 6 , 0 , 5 , 3 )
197+ layout .addWidget (self .messages_label , 4 , 0 )
198+ layout .addWidget (self .messageBox , 5 , 0 , 5 , 3 )
184199
185200 self .setLayout (layout )
186201
@@ -208,11 +223,11 @@ def _load_settings(self) -> None:
208223 if lastFile is not None :
209224 self .fileLocation_lineedit .setText (lastFile )
210225
211- lastFile = self .settings .value (SETTING_PARTITION_LOCATION )
212- if lastFile is not None :
213- self .partitionFileLocation_lineedit .setText (lastFile )
214- else :
215- self .partitionFileLocation_lineedit .setText (resource_path ("RTK_Surveyor.ino.partitions.bin" ))
226+ # lastFile = self.settings.value(SETTING_PARTITION_LOCATION)
227+ # if lastFile is not None:
228+ # self.partitionFileLocation_lineedit.setText(lastFile)
229+ # else:
230+ # self.partitionFileLocation_lineedit.setText(resource_path("RTK_Surveyor.ino.partitions.bin"))
216231
217232 baud = self .settings .value (SETTING_BAUD_RATE )
218233 if baud is not None :
@@ -224,7 +239,7 @@ def _save_settings(self) -> None:
224239 """Save settings on shutdown."""
225240 self .settings .setValue (SETTING_PORT_NAME , self .port )
226241 self .settings .setValue (SETTING_FILE_LOCATION , self .theFileName )
227- self .settings .setValue (SETTING_PARTITION_LOCATION , self .thePartitionFileName )
242+ # self.settings.setValue(SETTING_PARTITION_LOCATION, self.thePartitionFileName)
228243 self .settings .setValue (SETTING_BAUD_RATE , self .baudRate )
229244
230245 def _clean_settings (self ) -> None :
@@ -277,10 +292,10 @@ def theFileName(self) -> str:
277292 """Return the file name."""
278293 return self .fileLocation_lineedit .text ()
279294
280- @property
281- def thePartitionFileName (self ) -> str :
282- """Return the partition file name."""
283- return self .partitionFileLocation_lineedit .text ()
295+ # @property
296+ # def thePartitionFileName(self) -> str:
297+ # """Return the partition file name."""
298+ # return self.partitionFileLocation_lineedit.text()
284299
285300 def closeEvent (self , event : QCloseEvent ) -> None :
286301 """Handle Close event of the Widget."""
@@ -307,17 +322,17 @@ def on_browse_btn_pressed(self) -> None:
307322 if fileName :
308323 self .fileLocation_lineedit .setText (fileName )
309324
310- def on_partition_browse_btn_pressed (self ) -> None :
311- """Open dialog to select partition bin file."""
312- options = QFileDialog .Options ()
313- fileName , _ = QFileDialog .getOpenFileName (
314- None ,
315- "Select Partition File" ,
316- "" ,
317- "Parition Files (*.bin);;All Files (*)" ,
318- options = options )
319- if fileName :
320- self .partitionFileLocation_lineedit .setText (fileName )
325+ # def on_partition_browse_btn_pressed(self) -> None:
326+ # """Open dialog to select partition bin file."""
327+ # options = QFileDialog.Options()
328+ # fileName, _ = QFileDialog.getOpenFileName(
329+ # None,
330+ # "Select Partition File",
331+ # "",
332+ # "Parition Files (*.bin);;All Files (*)",
333+ # options=options)
334+ # if fileName:
335+ # self.partitionFileLocation_lineedit.setText(fileName)
321336
322337 def on_upload_btn_pressed (self ) -> None :
323338 """Upload the firmware"""
@@ -331,7 +346,7 @@ def on_upload_btn_pressed(self) -> None:
331346
332347 fileExists = False
333348 try :
334- f = open (self .fileLocation_lineedit . text () )
349+ f = open (self .theFileName )
335350 fileExists = True
336351 except IOError :
337352 fileExists = False
@@ -341,11 +356,67 @@ def on_upload_btn_pressed(self) -> None:
341356 return
342357 f .close ()
343358
359+ # fileExists = False
360+ # try:
361+ # f = open(self.thePartitionFileName)
362+ # fileExists = True
363+ # except IOError:
364+ # fileExists = False
365+ # finally:
366+ # if (fileExists == False):
367+ # self.writeMessage("File Not Found")
368+ # return
369+ # f.close()
370+
344371 try :
345372 self ._save_settings () # Save the settings in case the upload crashes
346373 except :
347374 pass
348375
376+ self .flashSize [0 ] = 0
377+
378+ self .writeMessage ("Detecting flash size\n \n " )
379+
380+ command = []
381+ command .extend (["--chip" ,"esp32" ])
382+ command .extend (["--port" ,self .port ])
383+ command .extend (["--baud" ,self .baudRate ])
384+ command .extend (["flash_id" ])
385+
386+ try :
387+ esptool .main (command )
388+ except (ValueError , IOError , FatalError , ImportError , NotImplementedInROMError , UnsupportedCommandError , NotSupportedError , RuntimeError ) as err :
389+ self .writeMessage (str (err ))
390+ self .messageBox .ensureCursorVisible ()
391+ self .messageBox .repaint ()
392+ return
393+ except :
394+ self .messageBox .ensureCursorVisible ()
395+ self .messageBox .repaint ()
396+ return
397+
398+ if self .flashSize [0 ] == 0 :
399+ self .writeMessage ("Flash size not detected! Defaulting to 16MB\n " )
400+ self .flashSize [0 ] = 16
401+ else :
402+ self .writeMessage ("Flash size is " + str (self .flashSize [0 ]) + "MB\n " )
403+
404+ thePartitionFileName = ''
405+ firmwareSizeCorrect = True
406+ if self .flashSize [0 ] == 16 :
407+ thePartitionFileName = resource_path ("RTK_Surveyor_Partitions_16MB.bin" )
408+ # if self.theFileName.find("16MB") < 0:
409+ # firmwareSizeCorrect = False
410+ else :
411+ thePartitionFileName = resource_path ("RTK_Surveyor_Partitions_4MB.bin" )
412+ # if self.theFileName.find("4MB") < 0:
413+ # firmwareSizeCorrect = False
414+
415+ if firmwareSizeCorrect == False :
416+ reply = QMessageBox .warning (self , "Firmware size mismatch" , "Do you want to continue?" , QMessageBox .Yes | QMessageBox .No , QMessageBox .No )
417+ if reply == QMessageBox .No :
418+ return
419+
349420 self .writeMessage ("Uploading firmware\n " )
350421
351422 command = []
@@ -355,7 +426,7 @@ def on_upload_btn_pressed(self) -> None:
355426 command .extend (["--baud" ,self .baudRate ])
356427 command .extend (["--before" ,"default_reset" ,"--after" ,"hard_reset" ,"write_flash" ,"-z" ,"--flash_mode" ,"dio" ,"--flash_freq" ,"80m" ,"--flash_size" ,"detect" ])
357428 command .extend (["0x1000" ,resource_path ("RTK_Surveyor.ino.bootloader.bin" )])
358- command .extend (["0x8000" ,self . thePartitionFileName ])
429+ command .extend (["0x8000" ,thePartitionFileName ])
359430 command .extend (["0xe000" ,resource_path ("boot_app0.bin" )])
360431 command .extend (["0x10000" ,self .theFileName ])
361432
@@ -380,11 +451,11 @@ def on_upload_btn_pressed(self) -> None:
380451 app .setApplicationName ('SparkFun RTK Firmware Uploader ' + guiVersion )
381452 app .setWindowIcon (QIcon (resource_path ("RTK.png" )))
382453 w = MainWidget ()
383- if 0 : # Change to 0 to have the messages echoed on stdout
384- sys .stdout = messageRedirect (w .messageBox ) # Divert stdout to messageBox
454+ if 1 : # Change to 0 to have the messages echoed on stdout
455+ sys .stdout = messageRedirect (w .messageBox , flashSize = w . flashSize ) # Divert stdout to messageBox. Report flash size via flashSize
385456 sys .stderr = messageRedirect (w .messageBox ) # Divert stderr to messageBox
386457 else :
387- sys .stdout = messageRedirect (w .messageBox , sys .stdout ) # Echo to stdout too
388- sys .stderr = messageRedirect (w .messageBox , sys .stderr ) # Echo to stderr too
458+ sys .stdout = messageRedirect (w .messageBox , flashSize = w . flashSize , out = sys .stdout ) # Echo to stdout too
459+ sys .stderr = messageRedirect (w .messageBox , out = sys .stderr ) # Echo to stderr too
389460 w .show ()
390461 sys .exit (app .exec_ ())
0 commit comments