6 """ |
6 """ |
7 Module implementing the device interface class for RP2040 based boards |
7 Module implementing the device interface class for RP2040 based boards |
8 (e.g. Raspberry Pi Pico). |
8 (e.g. Raspberry Pi Pico). |
9 """ |
9 """ |
10 |
10 |
11 from PyQt6.QtCore import pyqtSlot |
11 from PyQt6.QtCore import QUrl, pyqtSlot |
12 |
12 from PyQt6.QtNetwork import QNetworkRequest |
13 from eric7 import Preferences |
13 |
14 |
14 from eric7 import Globals, Preferences |
15 from .MicroPythonDevices import MicroPythonDevice |
15 from eric7.EricWidgets import EricMessageBox |
|
16 from eric7.EricWidgets.EricApplication import ericApp |
|
17 |
|
18 from .MicroPythonDevices import FirmwareGithubUrls, MicroPythonDevice |
16 from .MicroPythonWidget import HAS_QTCHART |
19 from .MicroPythonWidget import HAS_QTCHART |
17 |
20 |
18 |
21 |
19 class RP2040Device(MicroPythonDevice): |
22 class RP2040Device(MicroPythonDevice): |
20 """ |
23 """ |
119 @param menu reference to the context menu |
122 @param menu reference to the context menu |
120 @type QMenu |
123 @type QMenu |
121 """ |
124 """ |
122 connected = self.microPython.isConnected() |
125 connected = self.microPython.isConnected() |
123 |
126 |
124 act = menu.addAction(self.tr("Activate Bootloader"), self.__activateBootloader) |
127 menu.addAction( |
125 act.setEnabled(connected) |
128 self.tr("Show MicroPython Versions"), self.__showFirmwareVersions |
126 act = menu.addAction(self.tr("Flash Firmware"), self.__flashPython) |
129 ).setEnabled(connected) |
127 act.setEnabled(not connected) |
130 menu.addAction( |
|
131 self.tr("Activate Bootloader"), self.__activateBootloader |
|
132 ).setEnabled(connected) |
|
133 menu.addAction( |
|
134 self.tr("Flash MicroPython Firmware"), self.__flashPython |
|
135 ).setEnabled(not connected) |
128 |
136 |
129 def hasFlashMenuEntry(self): |
137 def hasFlashMenuEntry(self): |
130 """ |
138 """ |
131 Public method to check, if the device has its own flash menu entry. |
139 Public method to check, if the device has its own flash menu entry. |
132 |
140 |
157 ] |
165 ] |
158 ) |
166 ) |
159 # simulate pressing the disconnect button |
167 # simulate pressing the disconnect button |
160 self.microPython.on_connectButton_clicked() |
168 self.microPython.on_connectButton_clicked() |
161 |
169 |
|
170 @pyqtSlot() |
|
171 def __showFirmwareVersions(self): |
|
172 """ |
|
173 Private slot to show the firmware version of the connected device and the |
|
174 available firmware version. |
|
175 """ |
|
176 if self.microPython.isConnected(): |
|
177 interface = self.microPython.commandsInterface() |
|
178 if interface is not None: |
|
179 impInfo = interface.getImplementation() |
|
180 if impInfo["name"] != "micropython": |
|
181 EricMessageBox.critical( |
|
182 None, |
|
183 self.tr("Show MicroPython Versions"), |
|
184 self.tr( |
|
185 """The firmware of the connected device cannot be""" |
|
186 """ determined or the board does not run MicroPython.""" |
|
187 """ Aborting...""" |
|
188 ), |
|
189 ) |
|
190 else: |
|
191 if impInfo["variant"] == "Pimoroni": |
|
192 # MicroPython with Pimoroni add-on libraries |
|
193 url = QUrl(FirmwareGithubUrls["pimoroni_pico"]) |
|
194 else: |
|
195 url = QUrl(FirmwareGithubUrls["micropython"]) |
|
196 ui = ericApp().getObject("UserInterface") |
|
197 request = QNetworkRequest(url) |
|
198 reply = ui.networkAccessManager().head(request) |
|
199 reply.finished.connect( |
|
200 lambda: self.__firmwareVersionResponse( |
|
201 reply, impInfo |
|
202 ) |
|
203 ) |
|
204 |
|
205 def __firmwareVersionResponse(self, reply, implementation): |
|
206 """ |
|
207 Private method handling the response of the latest version request. |
|
208 |
|
209 @param reply reference to the reply object |
|
210 @type QNetworkReply |
|
211 @param implementation dictionary containing the implementation data of the |
|
212 connected device |
|
213 @type dict |
|
214 """ |
|
215 latestUrl = reply.url().toString() |
|
216 tag = latestUrl.rsplit("/", 1)[-1] |
|
217 while tag and not tag[0].isdecimal(): |
|
218 # get rid of leading non-decimal characters |
|
219 tag = tag[1:] |
|
220 latestVersion = Globals.versionToTuple(tag) |
|
221 |
|
222 if implementation["version"] == "unknown": |
|
223 currentVersionStr = self.tr("unknown") |
|
224 currentVersion = (0, 0, 0) |
|
225 else: |
|
226 currentVersionStr = implementation["version"] |
|
227 currentVersion = Globals.versionToTuple(currentVersionStr) |
|
228 |
|
229 msg = self.tr( |
|
230 "<h4>MicroPython Version Information</h4>" |
|
231 "<table>" |
|
232 "<tr><td>Installed:</td><td>{0}</td><td></td></tr>" |
|
233 "<tr><td>Available:</td><td>{1}</td><td></td>{2}</tr>" |
|
234 "</table>" |
|
235 ).format( |
|
236 currentVersionStr, |
|
237 tag, |
|
238 self.tr("({0})").format(implementation["variant"]) |
|
239 if implementation["variant"] |
|
240 else "", |
|
241 ) |
|
242 if ( |
|
243 implementation["variant"] not in ["Pimoroni"] |
|
244 and currentVersion < latestVersion |
|
245 ): |
|
246 # cannot derive that info for 'Pimoroni' variant |
|
247 msg += self.tr("<p><b>Update available!</b></p>") |
|
248 |
|
249 EricMessageBox.information( |
|
250 None, |
|
251 self.tr("MicroPython Version"), |
|
252 msg, |
|
253 ) |
|
254 |
162 def getDocumentationUrl(self): |
255 def getDocumentationUrl(self): |
163 """ |
256 """ |
164 Public method to get the device documentation URL. |
257 Public method to get the device documentation URL. |
165 |
258 |
166 @return documentation URL of the device |
259 @return documentation URL of the device |
179 return [ |
272 return [ |
180 ( |
273 ( |
181 self.tr("MicroPython Firmware"), |
274 self.tr("MicroPython Firmware"), |
182 Preferences.getMicroPython("MicroPythonFirmwareUrl"), |
275 Preferences.getMicroPython("MicroPythonFirmwareUrl"), |
183 ), |
276 ), |
|
277 ("<separator>", ""), |
|
278 ( |
|
279 self.tr("Pimoroni Pico Firmware"), FirmwareGithubUrls["pimoroni_pico"] |
|
280 ), |
184 ("<separator>", ""), |
281 ("<separator>", ""), |
185 ( |
282 ( |
186 self.tr("CircuitPython Firmware"), |
283 self.tr("CircuitPython Firmware"), |
187 Preferences.getMicroPython("CircuitPythonFirmwareUrl"), |
284 Preferences.getMicroPython("CircuitPythonFirmwareUrl"), |
188 ), |
285 ), |