8 """ |
8 """ |
9 |
9 |
10 import os |
10 import os |
11 import shutil |
11 import shutil |
12 |
12 |
13 from PyQt6.QtCore import QUrl, pyqtSlot |
13 from PyQt6.QtCore import QProcess, QUrl, pyqtSlot |
14 from PyQt6.QtNetwork import QNetworkRequest |
14 from PyQt6.QtNetwork import QNetworkRequest |
15 from PyQt6.QtWidgets import QMenu |
15 from PyQt6.QtWidgets import QMenu |
16 |
16 |
17 from eric7 import Globals, Preferences |
17 from eric7 import Globals, Preferences |
18 from eric7.EricWidgets import EricFileDialog, EricMessageBox |
18 from eric7.EricWidgets import EricFileDialog, EricMessageBox |
51 |
51 |
52 self.__boardName = boardName |
52 self.__boardName = boardName |
53 self.__workspace = self.__findWorkspace() |
53 self.__workspace = self.__findWorkspace() |
54 |
54 |
55 self.__updater = CircuitPythonUpdaterInterface(self) |
55 self.__updater = CircuitPythonUpdaterInterface(self) |
56 |
|
57 self.__nonUF2devices = { |
|
58 "teensy": self.__flashTeensy, |
|
59 } |
|
60 |
56 |
61 self.__createCPyMenu() |
57 self.__createCPyMenu() |
62 |
58 |
63 def setButtons(self): |
59 def setButtons(self): |
64 """ |
60 """ |
254 |
250 |
255 self.__cpyMenu.addAction( |
251 self.__cpyMenu.addAction( |
256 self.tr("Show CircuitPython Versions"), self.__showCircuitPythonVersions |
252 self.tr("Show CircuitPython Versions"), self.__showCircuitPythonVersions |
257 ) |
253 ) |
258 self.__cpyMenu.addSeparator() |
254 self.__cpyMenu.addSeparator() |
259 self.__flashCpyAct = self.__cpyMenu.addAction( |
255 |
260 self.tr("Flash CircuitPython Firmware"), self.__flashCircuitPython |
256 lBoardName = self.microPython.getCurrentBoard().lower() |
261 ) |
257 if "teensy" in lBoardName: |
|
258 # Teensy 4.0 and 4.1 don't support UF2 flashing |
|
259 self.__cpyMenu.addAction( |
|
260 self.tr("CircuitPython Flash Instructions"), |
|
261 self.__showTeensyFlashInstructions, |
|
262 ) |
|
263 self.__flashCpyAct = self.__cpyMenu.addAction( |
|
264 self.tr("Flash CircuitPython Firmware"), self.__startTeensyLoader |
|
265 ) |
|
266 self.__flashCpyAct.setToolTip( |
|
267 self.tr( |
|
268 "Start the 'Teensy Loader' application to flash the Teensy device." |
|
269 ) |
|
270 ) |
|
271 else: |
|
272 self.__flashCpyAct = self.__cpyMenu.addAction( |
|
273 self.tr("Flash CircuitPython Firmware"), self.__flashCircuitPython |
|
274 ) |
262 self.__cpyMenu.addSeparator() |
275 self.__cpyMenu.addSeparator() |
263 self.__cpyMenu.addMenu(self.__libraryMenu) |
276 self.__cpyMenu.addMenu(self.__libraryMenu) |
264 |
|
265 |
277 |
266 def addDeviceMenuEntries(self, menu): |
278 def addDeviceMenuEntries(self, menu): |
267 """ |
279 """ |
268 Public method to add device specific entries to the given menu. |
280 Public method to add device specific entries to the given menu. |
269 |
281 |
311 return True |
323 return True |
312 |
324 |
313 @pyqtSlot() |
325 @pyqtSlot() |
314 def __flashCircuitPython(self): |
326 def __flashCircuitPython(self): |
315 """ |
327 """ |
316 Private slot to flash a CircuitPython firmware to the device. |
328 Private slot to flash a CircuitPython firmware to a device supporting UF2. |
317 """ |
329 """ |
318 from .UF2FlashDialog import UF2FlashDialog |
330 from .UF2FlashDialog import UF2FlashDialog |
319 |
331 |
320 lBoardName = self.microPython.getCurrentBoard().lower() |
332 dlg = UF2FlashDialog(boardType="circuitpython") |
321 if lBoardName: |
333 dlg.exec() |
322 for name in self.__nonUF2devices: |
334 |
323 if name in lBoardName: |
335 def __showTeensyFlashInstructions(self): |
324 self.__nonUF2devices[name]() |
336 """ |
325 break |
337 Private method to show a message box because Teensy does not support |
326 else: |
|
327 dlg = UF2FlashDialog(boardType="circuitpython") |
|
328 dlg.exec() |
|
329 |
|
330 def __flashTeensy(self): |
|
331 """ |
|
332 Private method to show a message box because Teens does not support |
|
333 the UF2 bootloader yet. |
338 the UF2 bootloader yet. |
334 """ |
339 """ |
335 EricMessageBox.information( |
340 EricMessageBox.information( |
336 self.microPython, |
341 self.microPython, |
337 self.tr("Flash CircuitPython Firmware"), |
342 self.tr("Flash CircuitPython Firmware"), |
342 """ downloaded the CircuitPython .hex file.</p>""" |
347 """ downloaded the CircuitPython .hex file.</p>""" |
343 """<p>See <a href="{0}">the PJRC Teensy web site</a>""" |
348 """<p>See <a href="{0}">the PJRC Teensy web site</a>""" |
344 """ for details.</p>""" |
349 """ for details.</p>""" |
345 ).format("https://www.pjrc.com/teensy/loader.html"), |
350 ).format("https://www.pjrc.com/teensy/loader.html"), |
346 ) |
351 ) |
|
352 |
|
353 def __startTeensyLoader(self): |
|
354 """ |
|
355 Private method to start the 'Teensy Loader' application. |
|
356 |
|
357 Note: The application must be accessible via the application search path. |
|
358 """ |
|
359 ok, _ = QProcess.startDetached("teensy") |
|
360 if not ok: |
|
361 EricMessageBox.warning( |
|
362 self.microPython, |
|
363 self.tr("Start 'Teensy Loader'"), |
|
364 self.tr( |
|
365 """<p>The 'Teensy Loader' application <b>teensy</b> could not""" |
|
366 """ be started. Ensure it is in the application search path or""" |
|
367 """ start it manually.</p>""" |
|
368 ), |
|
369 ) |
347 |
370 |
348 @pyqtSlot() |
371 @pyqtSlot() |
349 def __showCircuitPythonVersions(self): |
372 def __showCircuitPythonVersions(self): |
350 """ |
373 """ |
351 Private slot to show the CircuitPython version of a connected device and |
374 Private slot to show the CircuitPython version of a connected device and |