181 Public method to add device specific entries to the given menu. |
186 Public method to add device specific entries to the given menu. |
182 |
187 |
183 @param menu reference to the context menu |
188 @param menu reference to the context menu |
184 @type QMenu |
189 @type QMenu |
185 """ |
190 """ |
186 menu.addAction( |
191 connected = self.microPython.isConnected() |
187 self.tr("MicroPython Install Instructions"), |
192 |
188 self.__showInstallInstructions) |
193 act = menu.addAction(self.tr("List DFU-capable Devices"), |
189 # TODO: add entry to flash a new firmware using dfu-util |
194 self.__listDfuCapableDevices) |
190 |
195 act.setEnabled(not connected) |
191 def __showInstallInstructions(self): |
196 act = menu.addAction(self.tr("Flash MicroPython Firmware"), |
|
197 self.__flashMicroPython) |
|
198 act.setEnabled(not connected) |
|
199 menu.addSeparator() |
|
200 menu.addAction(self.tr("MicroPython Flash Instructions"), |
|
201 self.__showFlashInstructions) |
|
202 |
|
203 @pyqtSlot() |
|
204 def __showFlashInstructions(self): |
192 """ |
205 """ |
193 Private slot to open the URL containing instructions for installing |
206 Private slot to open the URL containing instructions for installing |
194 MicroPython on the pyboard. |
207 MicroPython on the pyboard. |
195 """ |
208 """ |
196 e5App().getObject("UserInterface").launchHelpViewer( |
209 e5App().getObject("UserInterface").launchHelpViewer( |
197 PyBoardDevice.FlashInstructionsURL) |
210 PyBoardDevice.FlashInstructionsURL) |
|
211 |
|
212 def __dfuUtilAvailable(self): |
|
213 """ |
|
214 Private method to check the availability of dfu-util. |
|
215 |
|
216 @return flag indicating the availability of dfu-util |
|
217 @rtype bool |
|
218 """ |
|
219 available = False |
|
220 program = Preferences.getMicroPython("DfuUtilPath") |
|
221 if not program: |
|
222 program = "dfu-util" |
|
223 if Utilities.isinpath(program): |
|
224 available = True |
|
225 else: |
|
226 if Utilities.isExecutable(program): |
|
227 available = True |
|
228 |
|
229 if not available: |
|
230 E5MessageBox.critical( |
|
231 self.microPython, |
|
232 self.tr("dfu-util not available"), |
|
233 self.tr("""The dfu-util firmware flashing tool""" |
|
234 """ <b>dfu-util</b> cannot be found or is not""" |
|
235 """ executable. Ensure it is in the search path""" |
|
236 """ or configure it on the MicroPython""" |
|
237 """ configuration page.""") |
|
238 ) |
|
239 |
|
240 return available |
|
241 |
|
242 def __showDfuEnableInstructions(self, flash=True): |
|
243 """ |
|
244 Private method to show some instructions to enable the DFU mode. |
|
245 |
|
246 @param flash flag indicating to show a warning message for flashing |
|
247 @type bool |
|
248 @return flag indicating OK to continue or abort |
|
249 @rtype bool |
|
250 """ |
|
251 msg = self.tr( |
|
252 "<h3>Enable DFU Mode</h3>" |
|
253 "<p>1. Disconnect everything from your board</p>" |
|
254 "<p>2. Disconnect your board</p>" |
|
255 "<p>3. Connect the DFU/BOOT0 pin with a 3.3V pin</p>" |
|
256 "<p>4. Re-connect your board</p>" |
|
257 "<hr />" |
|
258 ) |
|
259 |
|
260 if flash: |
|
261 msg += self.tr( |
|
262 "<p><b>Warning:</b> Make sure that all other DFU capable" |
|
263 " devices except your PyBoard are disconnected." |
|
264 "<hr />" |
|
265 ) |
|
266 |
|
267 msg += self.tr( |
|
268 "<p>Press <b>OK</b> to continue...</p>" |
|
269 ) |
|
270 res = E5MessageBox.information( |
|
271 self.microPython, |
|
272 self.tr("Enable DFU mode"), |
|
273 msg, |
|
274 E5MessageBox.StandardButtons( |
|
275 E5MessageBox.Abort | |
|
276 E5MessageBox.Ok)) |
|
277 |
|
278 return res == E5MessageBox.Ok |
|
279 |
|
280 def __showDfuDisableInstructions(self): |
|
281 """ |
|
282 Private method to show some instructions to disable the DFU mode. |
|
283 """ |
|
284 msg = self.tr( |
|
285 "<h3>Disable DFU Mode</h3>" |
|
286 "<p>1. Disconnect your board</p>" |
|
287 "<p>2. Remove the DFU jumper</p>" |
|
288 "<p>3. Re-connect your board</p>" |
|
289 "<hr />" |
|
290 "<p>Press <b>OK</b> to continue...</p>" |
|
291 ) |
|
292 E5MessageBox.information( |
|
293 self.microPython, |
|
294 self.tr("Disable DFU mode"), |
|
295 msg |
|
296 ) |
|
297 |
|
298 @pyqtSlot() |
|
299 def __listDfuCapableDevices(self): |
|
300 """ |
|
301 Private slot to list all DFU-capable devices. |
|
302 """ |
|
303 if self.__dfuUtilAvailable(): |
|
304 ok2continue = self.__showDfuEnableInstructions(flash=False) |
|
305 if ok2continue: |
|
306 program = Preferences.getMicroPython("DfuUtilPath") |
|
307 if not program: |
|
308 program = "dfu-util" |
|
309 |
|
310 args = [ |
|
311 "--list", |
|
312 ] |
|
313 dlg = E5ProcessDialog( |
|
314 self.tr("'dfu-util' Output"), |
|
315 self.tr("List DFU capable Devices") |
|
316 ) |
|
317 res = dlg.startProcess(program, args) |
|
318 if res: |
|
319 dlg.exec_() |
|
320 |
|
321 @pyqtSlot() |
|
322 def __flashMicroPython(self): |
|
323 """ |
|
324 Private slot to flash a MicroPython firmware. |
|
325 """ |
|
326 if self.__dfuUtilAvailable(): |
|
327 ok2continue = self.__showDfuEnableInstructions() |
|
328 if ok2continue: |
|
329 program = Preferences.getMicroPython("DfuUtilPath") |
|
330 if not program: |
|
331 program = "dfu-util" |
|
332 |
|
333 downloadsPath = QStandardPaths.standardLocations( |
|
334 QStandardPaths.DownloadLocation)[0] |
|
335 firmware = E5FileDialog.getOpenFileName( |
|
336 self.microPython, |
|
337 self.tr("Flash MicroPython Firmware"), |
|
338 downloadsPath, |
|
339 self.tr( |
|
340 "MicroPython Firmware Files (*.dfu);;All Files (*)") |
|
341 ) |
|
342 if firmware and os.path.exists(firmware): |
|
343 args = [ |
|
344 "--alt", "0", |
|
345 "--download", firmware, |
|
346 ] |
|
347 dlg = E5ProcessDialog( |
|
348 self.tr("'dfu-util' Output"), |
|
349 self.tr("Flash MicroPython Firmware") |
|
350 ) |
|
351 res = dlg.startProcess(program, args) |
|
352 if res: |
|
353 dlg.exec_() |
|
354 self.__showDfuDisableInstructions() |