FlashGBX 3.37__py3-none-any.whl → 4.0.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- FlashGBX/FlashGBX.py +14 -7
- FlashGBX/FlashGBX_CLI.py +201 -24
- FlashGBX/FlashGBX_GUI.py +636 -204
- FlashGBX/Flashcart.py +184 -83
- FlashGBX/GBMemory.py +4 -5
- FlashGBX/LK_Device.py +4533 -0
- FlashGBX/Mapper.py +534 -356
- FlashGBX/RomFileAGB.py +92 -2
- FlashGBX/RomFileDMG.py +1 -1
- FlashGBX/UserInputDialog.py +20 -0
- FlashGBX/Util.py +95 -47
- FlashGBX/fw_GBFlash.py +426 -0
- FlashGBX/fw_GBxCartRW_v1_3.py +1 -1
- FlashGBX/fw_JoeyJr.py +472 -0
- FlashGBX/hw_GBFlash.py +244 -0
- FlashGBX/hw_GBxCartRW.py +200 -3777
- FlashGBX/hw_JoeyJr.py +309 -0
- FlashGBX/res/Third Party Notices.md +342 -0
- FlashGBX/res/config.zip +0 -0
- FlashGBX/res/fw_GBFlash.zip +0 -0
- FlashGBX/res/fw_GBxCart_RW_v1_3.zip +0 -0
- FlashGBX/res/fw_GBxCart_RW_v1_4.zip +0 -0
- FlashGBX/res/fw_GBxCart_RW_v1_4a.zip +0 -0
- FlashGBX/res/fw_JoeyJr.zip +0 -0
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/METADATA +36 -16
- FlashGBX-4.0.1.dist-info/RECORD +43 -0
- FlashGBX/hw_GBxCartRW_ofw.py +0 -2599
- FlashGBX-3.37.dist-info/RECORD +0 -36
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/LICENSE +0 -0
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/WHEEL +0 -0
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/entry_points.txt +0 -0
- {FlashGBX-3.37.dist-info → FlashGBX-4.0.1.dist-info}/top_level.txt +0 -0
FlashGBX/fw_GBFlash.py
ADDED
|
@@ -0,0 +1,426 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
# FlashGBX
|
|
3
|
+
# Author: Lesserkuma (github.com/lesserkuma)
|
|
4
|
+
|
|
5
|
+
import zipfile, serial, struct, time, datetime
|
|
6
|
+
try:
|
|
7
|
+
from . import Util
|
|
8
|
+
except ImportError:
|
|
9
|
+
import Util
|
|
10
|
+
|
|
11
|
+
class FirmwareUpdater():
|
|
12
|
+
PORT = None
|
|
13
|
+
DEVICE = None
|
|
14
|
+
|
|
15
|
+
def __init__(self, app_path=".", port=None):
|
|
16
|
+
self.APP_PATH = app_path
|
|
17
|
+
self.PORT = port
|
|
18
|
+
|
|
19
|
+
def PackPacket(self, packet):
|
|
20
|
+
values = list(packet.values())[:-2]
|
|
21
|
+
data = struct.pack(">IBHHH", *values)
|
|
22
|
+
if packet["payload_len"] > 0:
|
|
23
|
+
data += list(packet.values())[-2]
|
|
24
|
+
data += struct.pack(">I", packet["outro"])
|
|
25
|
+
if len(data) % 2 == 1: data += b'\00'
|
|
26
|
+
return data
|
|
27
|
+
|
|
28
|
+
def GetPacket(self):
|
|
29
|
+
hp = 100
|
|
30
|
+
while self.DEVICE.in_waiting == 0:
|
|
31
|
+
time.sleep(0.001)
|
|
32
|
+
hp -= 1
|
|
33
|
+
if hp <= 0:
|
|
34
|
+
return None
|
|
35
|
+
keys = ["intro", "sender", "seq_no", "command", "payload_len"]
|
|
36
|
+
values = struct.unpack(">IBHHH", self.DEVICE.read(11))
|
|
37
|
+
data = dict(zip(keys, values))
|
|
38
|
+
data["payload"] = self.DEVICE.read(data["payload_len"])
|
|
39
|
+
data["outro"] = struct.unpack(">I", self.DEVICE.read(4))[0]
|
|
40
|
+
return data
|
|
41
|
+
|
|
42
|
+
def CRC16(self, data):
|
|
43
|
+
CRCTableAbs = [
|
|
44
|
+
0x0000, 0xCC01, 0xD801, 0x1400, 0xF001, 0x3C00, 0x2800, 0xE401,
|
|
45
|
+
0xA001, 0x6C00, 0x7800, 0xB401, 0x5000, 0x9C01, 0x8801, 0x4400,
|
|
46
|
+
]
|
|
47
|
+
wCRC = 0xFFFF
|
|
48
|
+
|
|
49
|
+
for i in range(len(data)):
|
|
50
|
+
chChar = data[i]
|
|
51
|
+
wCRC = (CRCTableAbs[(chChar ^ wCRC) & 0x0F] ^ (wCRC >> 4))
|
|
52
|
+
wCRC = (CRCTableAbs[((chChar >> 4) ^ wCRC) & 0x0F] ^ (wCRC >> 4))
|
|
53
|
+
|
|
54
|
+
return wCRC
|
|
55
|
+
|
|
56
|
+
def TryConnect(self, port):
|
|
57
|
+
seq_no = 1
|
|
58
|
+
packet = {
|
|
59
|
+
"intro":0x48484A4A,
|
|
60
|
+
"sender":0,
|
|
61
|
+
"seq_no":seq_no,
|
|
62
|
+
"command":0x21,
|
|
63
|
+
"payload_len":0,
|
|
64
|
+
"payload":bytearray(),
|
|
65
|
+
"outro":0x4A4A4848,
|
|
66
|
+
}
|
|
67
|
+
data = self.PackPacket(packet)
|
|
68
|
+
|
|
69
|
+
self.DEVICE = None
|
|
70
|
+
try:
|
|
71
|
+
self.DEVICE = serial.Serial(port, 2000000, timeout=0.1)
|
|
72
|
+
self.DEVICE.write(b'\xF1')
|
|
73
|
+
self.DEVICE.read(1)
|
|
74
|
+
self.DEVICE.write(b'\x01')
|
|
75
|
+
self.DEVICE.close()
|
|
76
|
+
time.sleep(3)
|
|
77
|
+
self.DEVICE = serial.Serial(port, 2000000, timeout=0.1)
|
|
78
|
+
|
|
79
|
+
except serial.serialutil.SerialException:
|
|
80
|
+
return False
|
|
81
|
+
|
|
82
|
+
self.DEVICE.write(data)
|
|
83
|
+
time.sleep(0.1)
|
|
84
|
+
self.DEVICE.read(self.DEVICE.in_waiting)
|
|
85
|
+
self.DEVICE.write(data)
|
|
86
|
+
data = self.GetPacket()
|
|
87
|
+
if data is None:
|
|
88
|
+
self.DEVICE = None
|
|
89
|
+
return False
|
|
90
|
+
if data["seq_no"] != seq_no:
|
|
91
|
+
self.DEVICE = None
|
|
92
|
+
return False
|
|
93
|
+
if data["command"] != 0x21:
|
|
94
|
+
self.DEVICE = None
|
|
95
|
+
return False
|
|
96
|
+
if struct.unpack(">H", data["payload"][1:3])[0] != 0x03:
|
|
97
|
+
self.DEVICE = None
|
|
98
|
+
return False
|
|
99
|
+
return data
|
|
100
|
+
|
|
101
|
+
def WriteFirmware(self, zipfn, fncSetStatus):
|
|
102
|
+
with zipfile.ZipFile(zipfn) as archive:
|
|
103
|
+
with archive.open("fw.bin") as f: fw_data = bytearray(f.read())
|
|
104
|
+
|
|
105
|
+
fncSetStatus("Connecting...")
|
|
106
|
+
if self.PORT is None:
|
|
107
|
+
ports = []
|
|
108
|
+
comports = serial.tools.list_ports.comports()
|
|
109
|
+
for i in range(0, len(comports)):
|
|
110
|
+
if comports[i].vid == 0x1A86 and comports[i].pid == 0x7523:
|
|
111
|
+
ports.append(comports[i].device)
|
|
112
|
+
if len(ports) == 0:
|
|
113
|
+
fncSetStatus("No device found.")
|
|
114
|
+
return 2
|
|
115
|
+
|
|
116
|
+
for port in ports:
|
|
117
|
+
data = self.TryConnect(port)
|
|
118
|
+
if data is not False:
|
|
119
|
+
break
|
|
120
|
+
else:
|
|
121
|
+
data = self.TryConnect(self.PORT)
|
|
122
|
+
|
|
123
|
+
if self.DEVICE is None:
|
|
124
|
+
fncSetStatus("No device found.")
|
|
125
|
+
return 2
|
|
126
|
+
|
|
127
|
+
data["program_size"] = struct.unpack(">H", data["payload"][3:5])[0]
|
|
128
|
+
data["page_size"] = struct.unpack(">H", data["payload"][7:9])[0]
|
|
129
|
+
page_size = data["page_size"]
|
|
130
|
+
num_packets = len(fw_data) / page_size
|
|
131
|
+
num_packets = int(-(-num_packets // 1)) # round up
|
|
132
|
+
|
|
133
|
+
fncSetStatus("Updating firmware...", setProgress=0)
|
|
134
|
+
seq_no = 2
|
|
135
|
+
|
|
136
|
+
pos = 0
|
|
137
|
+
packet_index = 1
|
|
138
|
+
while pos < num_packets:
|
|
139
|
+
buffer = fw_data[pos*page_size:pos*page_size+page_size]
|
|
140
|
+
packet_len = len(buffer)
|
|
141
|
+
buffer += struct.pack(">H", self.CRC16(buffer))
|
|
142
|
+
buffer = struct.pack(">H", packet_len) + buffer
|
|
143
|
+
buffer = struct.pack(">H", packet_index) + buffer
|
|
144
|
+
|
|
145
|
+
packet = {
|
|
146
|
+
"intro":0x48484A4A,
|
|
147
|
+
"sender":0,
|
|
148
|
+
"seq_no":seq_no,
|
|
149
|
+
"command":0x24,
|
|
150
|
+
"payload_len":len(buffer),
|
|
151
|
+
"payload":buffer,
|
|
152
|
+
"outro":0x4A4A4848,
|
|
153
|
+
}
|
|
154
|
+
data = self.PackPacket(packet)
|
|
155
|
+
|
|
156
|
+
self.DEVICE.write(data)
|
|
157
|
+
data = self.GetPacket()
|
|
158
|
+
|
|
159
|
+
if data["seq_no"] != seq_no:
|
|
160
|
+
fncSetStatus("Incorrect sequence number.")
|
|
161
|
+
time.sleep(1)
|
|
162
|
+
continue
|
|
163
|
+
if data["command"] != 0x24:
|
|
164
|
+
fncSetStatus("Incorrect command.")
|
|
165
|
+
time.sleep(1)
|
|
166
|
+
continue
|
|
167
|
+
if struct.unpack(">H", data["payload"][0:2])[0] != packet_index:
|
|
168
|
+
fncSetStatus("Incorrect data packet number.")
|
|
169
|
+
time.sleep(1)
|
|
170
|
+
continue
|
|
171
|
+
if data["payload"][2] != 0x01:
|
|
172
|
+
fncSetStatus("Write failed.")
|
|
173
|
+
time.sleep(1)
|
|
174
|
+
continue
|
|
175
|
+
|
|
176
|
+
percent = packet_index / num_packets * 100
|
|
177
|
+
fncSetStatus(text="Updating firmware... Do not unplug the device!", setProgress=percent)
|
|
178
|
+
pos += 1
|
|
179
|
+
seq_no += 1
|
|
180
|
+
packet_index += 1
|
|
181
|
+
|
|
182
|
+
if pos == num_packets:
|
|
183
|
+
payload = bytearray()
|
|
184
|
+
payload += struct.pack(">H", self.CRC16(fw_data))
|
|
185
|
+
payload += struct.pack(">H", ~self.CRC16(fw_data) & 0xFFFF)
|
|
186
|
+
packet = {
|
|
187
|
+
"intro":0x48484A4A,
|
|
188
|
+
"sender":0,
|
|
189
|
+
"seq_no":seq_no,
|
|
190
|
+
"command":0x23,
|
|
191
|
+
"payload_len":4,
|
|
192
|
+
"payload":payload,
|
|
193
|
+
"outro":0x4A4A4848,
|
|
194
|
+
}
|
|
195
|
+
data = self.PackPacket(packet)
|
|
196
|
+
self.DEVICE.write(data)
|
|
197
|
+
data = self.GetPacket()
|
|
198
|
+
if data["payload"][0] != 1:
|
|
199
|
+
fncSetStatus(text="Update failed!", enableUI=True)
|
|
200
|
+
|
|
201
|
+
self.DEVICE.close()
|
|
202
|
+
time.sleep(0.8)
|
|
203
|
+
fncSetStatus("Done.")
|
|
204
|
+
time.sleep(0.2)
|
|
205
|
+
return 1
|
|
206
|
+
|
|
207
|
+
try:
|
|
208
|
+
from .pyside import QtCore, QtWidgets, QtGui, QDesktopWidget
|
|
209
|
+
class FirmwareUpdaterWindow(QtWidgets.QDialog):
|
|
210
|
+
APP = None
|
|
211
|
+
DEVICE = None
|
|
212
|
+
FWUPD = None
|
|
213
|
+
DEV_NAME = "GBFlash"
|
|
214
|
+
FW_VER = ""
|
|
215
|
+
PCB_VER = ""
|
|
216
|
+
|
|
217
|
+
def __init__(self, app, app_path, file=None, icon=None, device=None):
|
|
218
|
+
QtWidgets.QDialog.__init__(self)
|
|
219
|
+
if icon is not None: self.setWindowIcon(QtGui.QIcon(icon))
|
|
220
|
+
self.setStyleSheet("QMessageBox { messagebox-text-interaction-flags: 5; }")
|
|
221
|
+
self.setWindowTitle("FlashGBX – Firmware Updater for GBFlash")
|
|
222
|
+
self.setWindowFlags((self.windowFlags() | QtCore.Qt.MSWindowsFixedSizeDialogHint) & ~QtCore.Qt.WindowContextHelpButtonHint)
|
|
223
|
+
|
|
224
|
+
self.APP = app
|
|
225
|
+
if device is not None:
|
|
226
|
+
self.FWUPD = FirmwareUpdater(app_path, device.GetPort())
|
|
227
|
+
self.DEV_NAME = device.GetName()
|
|
228
|
+
self.FW_VER = device.GetFirmwareVersion(more=True)
|
|
229
|
+
self.PCB_VER = device.GetPCBVersion()
|
|
230
|
+
self.DEVICE = device
|
|
231
|
+
else:
|
|
232
|
+
self.APP.QT_APP.processEvents()
|
|
233
|
+
text = "This Firmware Updater is for GBFlash devices only. Please only proceed if your device is a GBFlash."
|
|
234
|
+
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
|
|
235
|
+
msgbox.setDefaultButton(QtWidgets.QMessageBox.Ok)
|
|
236
|
+
answer = msgbox.exec()
|
|
237
|
+
if answer == QtWidgets.QMessageBox.Cancel: return
|
|
238
|
+
self.FWUPD = FirmwareUpdater(app_path, None)
|
|
239
|
+
|
|
240
|
+
self.layout = QtWidgets.QGridLayout()
|
|
241
|
+
self.layout.setContentsMargins(-1, 8, -1, 8)
|
|
242
|
+
self.layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
|
|
243
|
+
self.layout_device = QtWidgets.QVBoxLayout()
|
|
244
|
+
|
|
245
|
+
# ↓↓↓ Current Device Information
|
|
246
|
+
self.grpDeviceInfo = QtWidgets.QGroupBox("Current Firmware")
|
|
247
|
+
self.grpDeviceInfo.setMinimumWidth(420)
|
|
248
|
+
self.grpDeviceInfoLayout = QtWidgets.QVBoxLayout()
|
|
249
|
+
self.grpDeviceInfoLayout.setContentsMargins(-1, 3, -1, -1)
|
|
250
|
+
rowDeviceInfo1 = QtWidgets.QHBoxLayout()
|
|
251
|
+
self.lblDeviceName = QtWidgets.QLabel("Device:")
|
|
252
|
+
self.lblDeviceName.setMinimumWidth(120)
|
|
253
|
+
self.lblDeviceNameResult = QtWidgets.QLabel("GBFlash")
|
|
254
|
+
rowDeviceInfo1.addWidget(self.lblDeviceName)
|
|
255
|
+
rowDeviceInfo1.addWidget(self.lblDeviceNameResult)
|
|
256
|
+
rowDeviceInfo1.addStretch(1)
|
|
257
|
+
self.grpDeviceInfoLayout.addLayout(rowDeviceInfo1)
|
|
258
|
+
rowDeviceInfo3 = QtWidgets.QHBoxLayout()
|
|
259
|
+
self.lblDeviceFWVer = QtWidgets.QLabel("Firmware version:")
|
|
260
|
+
self.lblDeviceFWVer.setMinimumWidth(120)
|
|
261
|
+
self.lblDeviceFWVerResult = QtWidgets.QLabel("L12")
|
|
262
|
+
rowDeviceInfo3.addWidget(self.lblDeviceFWVer)
|
|
263
|
+
rowDeviceInfo3.addWidget(self.lblDeviceFWVerResult)
|
|
264
|
+
rowDeviceInfo3.addStretch(1)
|
|
265
|
+
self.grpDeviceInfoLayout.addLayout(rowDeviceInfo3)
|
|
266
|
+
self.grpDeviceInfo.setLayout(self.grpDeviceInfoLayout)
|
|
267
|
+
self.layout_device.addWidget(self.grpDeviceInfo)
|
|
268
|
+
# ↑↑↑ Current Device Information
|
|
269
|
+
|
|
270
|
+
# ↓↓↓ Available Firmware Updates
|
|
271
|
+
self.grpAvailableFwUpdates = QtWidgets.QGroupBox("Available Firmware")
|
|
272
|
+
self.grpAvailableFwUpdates.setMinimumWidth(400)
|
|
273
|
+
self.grpAvailableFwUpdatesLayout = QtWidgets.QVBoxLayout()
|
|
274
|
+
self.grpAvailableFwUpdatesLayout.setContentsMargins(-1, 3, -1, -1)
|
|
275
|
+
|
|
276
|
+
rowDeviceInfo4 = QtWidgets.QHBoxLayout()
|
|
277
|
+
self.lblDeviceFWVer2 = QtWidgets.QLabel("Firmware version:")
|
|
278
|
+
self.lblDeviceFWVer2.setMinimumWidth(120)
|
|
279
|
+
self.lblDeviceFWVer2Result = QtWidgets.QLabel("(Please choose the PCB version)")
|
|
280
|
+
rowDeviceInfo4.addWidget(self.lblDeviceFWVer2)
|
|
281
|
+
rowDeviceInfo4.addWidget(self.lblDeviceFWVer2Result)
|
|
282
|
+
rowDeviceInfo4.addStretch(1)
|
|
283
|
+
self.grpAvailableFwUpdatesLayout.addLayout(rowDeviceInfo4)
|
|
284
|
+
|
|
285
|
+
self.rowUpdate = QtWidgets.QHBoxLayout()
|
|
286
|
+
self.btnUpdate = QtWidgets.QPushButton("Install Firmware Update")
|
|
287
|
+
self.btnUpdate.setMinimumWidth(200)
|
|
288
|
+
self.btnUpdate.setContentsMargins(20, 20, 20, 20)
|
|
289
|
+
self.connect(self.btnUpdate, QtCore.SIGNAL("clicked()"), lambda: [ self.UpdateFirmware() ])
|
|
290
|
+
self.rowUpdate.addStretch()
|
|
291
|
+
self.rowUpdate.addWidget(self.btnUpdate)
|
|
292
|
+
self.rowUpdate.addStretch()
|
|
293
|
+
|
|
294
|
+
self.grpAvailableFwUpdatesLayout.addSpacing(3)
|
|
295
|
+
self.grpAvailableFwUpdatesLayout.addItem(self.rowUpdate)
|
|
296
|
+
self.grpAvailableFwUpdates.setLayout(self.grpAvailableFwUpdatesLayout)
|
|
297
|
+
self.layout_device.addWidget(self.grpAvailableFwUpdates)
|
|
298
|
+
# ↑↑↑ Available Firmware Updates
|
|
299
|
+
|
|
300
|
+
self.grpStatus = QtWidgets.QGroupBox("")
|
|
301
|
+
self.grpStatusLayout = QtWidgets.QGridLayout()
|
|
302
|
+
self.prgStatus = QtWidgets.QProgressBar()
|
|
303
|
+
self.prgStatus.setMinimum(0)
|
|
304
|
+
self.prgStatus.setMaximum(1000)
|
|
305
|
+
self.prgStatus.setValue(0)
|
|
306
|
+
self.lblStatus = QtWidgets.QLabel("Ready.")
|
|
307
|
+
|
|
308
|
+
self.grpStatusLayout.addWidget(self.prgStatus, 1, 0)
|
|
309
|
+
self.grpStatusLayout.addWidget(self.lblStatus, 2, 0)
|
|
310
|
+
|
|
311
|
+
self.grpStatus.setLayout(self.grpStatusLayout)
|
|
312
|
+
self.layout_device.addWidget(self.grpStatus)
|
|
313
|
+
|
|
314
|
+
self.grpFooterLayout = QtWidgets.QHBoxLayout()
|
|
315
|
+
self.btnClose = QtWidgets.QPushButton("&Close")
|
|
316
|
+
self.connect(self.btnClose, QtCore.SIGNAL("clicked()"), lambda: [ self.reject() ])
|
|
317
|
+
self.grpFooterLayout.addStretch()
|
|
318
|
+
self.grpFooterLayout.addWidget(self.btnClose)
|
|
319
|
+
self.layout_device.addItem(self.grpFooterLayout)
|
|
320
|
+
|
|
321
|
+
self.layout.addLayout(self.layout_device, 0, 0)
|
|
322
|
+
self.setLayout(self.layout)
|
|
323
|
+
|
|
324
|
+
self.lblDeviceNameResult.setText(self.DEV_NAME + " " + self.PCB_VER)
|
|
325
|
+
self.lblDeviceFWVerResult.setText(self.FW_VER)
|
|
326
|
+
self.SetPCBVersion()
|
|
327
|
+
|
|
328
|
+
def SetPCBVersion(self):
|
|
329
|
+
file_name = self.FWUPD.APP_PATH + "/res/fw_GBFlash.zip"
|
|
330
|
+
|
|
331
|
+
with zipfile.ZipFile(file_name) as zip:
|
|
332
|
+
with zip.open("fw.ini") as f: ini_file = f.read()
|
|
333
|
+
ini_file = ini_file.decode(encoding="utf-8")
|
|
334
|
+
self.INI = Util.IniSettings(ini=ini_file, main_section="Firmware")
|
|
335
|
+
self.OFW_VER = self.INI.GetValue("fw_ver")
|
|
336
|
+
self.OFW_BUILDTS = self.INI.GetValue("fw_buildts")
|
|
337
|
+
self.OFW_TEXT = self.INI.GetValue("fw_text")
|
|
338
|
+
|
|
339
|
+
self.lblDeviceFWVer2Result.setText("{:s} ({:s})".format(self.OFW_VER, datetime.datetime.fromtimestamp(int(self.OFW_BUILDTS)).astimezone().replace(microsecond=0).isoformat()))
|
|
340
|
+
|
|
341
|
+
def run(self):
|
|
342
|
+
try:
|
|
343
|
+
self.layout.update()
|
|
344
|
+
self.layout.activate()
|
|
345
|
+
screenGeometry = QDesktopWidget().screenGeometry(self)
|
|
346
|
+
x = (screenGeometry.width() - self.width()) / 2
|
|
347
|
+
y = (screenGeometry.height() - self.height()) / 2
|
|
348
|
+
self.move(x, y)
|
|
349
|
+
self.show()
|
|
350
|
+
except:
|
|
351
|
+
return
|
|
352
|
+
|
|
353
|
+
def hideEvent(self, event):
|
|
354
|
+
if self.DEVICE is None:
|
|
355
|
+
self.APP.ConnectDevice()
|
|
356
|
+
self.APP.activateWindow()
|
|
357
|
+
|
|
358
|
+
def reject(self):
|
|
359
|
+
if self.CloseDialog():
|
|
360
|
+
super().reject()
|
|
361
|
+
|
|
362
|
+
def CloseDialog(self):
|
|
363
|
+
if self.btnClose.isEnabled() is False:
|
|
364
|
+
text = "<b>WARNING:</b> If you close this window while a firmware update is still running, it may leave the device in an unbootable state. You can still recover it by running the Firmware Updater again later.<br><br>Are you sure you want to close this window?"
|
|
365
|
+
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Warning, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.No)
|
|
366
|
+
msgbox.setDefaultButton(QtWidgets.QMessageBox.No)
|
|
367
|
+
answer = msgbox.exec()
|
|
368
|
+
if answer == QtWidgets.QMessageBox.No: return False
|
|
369
|
+
return True
|
|
370
|
+
|
|
371
|
+
def UpdateFirmware(self):
|
|
372
|
+
file_name = self.FWUPD.APP_PATH + "/res/fw_GBFlash.zip"
|
|
373
|
+
|
|
374
|
+
if self.APP.CONN is None or self.APP.CONN.BootloaderReset() is False:
|
|
375
|
+
self.APP.DisconnectDevice()
|
|
376
|
+
text = "Please follow these steps to proceed with the firmware update:<ol><li>Unplug your GBFlash device.</li><li>On your GBFlash circuit board, push and hold the small button (U22) while plugging the USB cable back in.</li><li>If done right, the blue LED labeled “ACT” should now keep blinking twice.</li><li>Click OK to continue.</li></ol>"
|
|
377
|
+
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Information, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok | QtWidgets.QMessageBox.Cancel)
|
|
378
|
+
msgbox.setDefaultButton(QtWidgets.QMessageBox.Ok)
|
|
379
|
+
msgbox.setTextFormat(QtCore.Qt.TextFormat.RichText)
|
|
380
|
+
answer = msgbox.exec()
|
|
381
|
+
if answer == QtWidgets.QMessageBox.Cancel: return
|
|
382
|
+
else:
|
|
383
|
+
self.APP.DisconnectDevice()
|
|
384
|
+
time.sleep(1)
|
|
385
|
+
|
|
386
|
+
self.btnUpdate.setEnabled(False)
|
|
387
|
+
self.btnClose.setEnabled(False)
|
|
388
|
+
|
|
389
|
+
while True:
|
|
390
|
+
ret = self.FWUPD.WriteFirmware(file_name, self.SetStatus)
|
|
391
|
+
if ret == 1:
|
|
392
|
+
text = "The firmware update is complete!"
|
|
393
|
+
if self.PCB_VER != "v1.3":
|
|
394
|
+
text += "\n\nPlease re-connect the USB cable now."
|
|
395
|
+
self.btnUpdate.setEnabled(True)
|
|
396
|
+
self.btnClose.setEnabled(True)
|
|
397
|
+
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Information, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok)
|
|
398
|
+
answer = msgbox.exec()
|
|
399
|
+
self.DEVICE = None
|
|
400
|
+
self.reject()
|
|
401
|
+
return True
|
|
402
|
+
elif ret == 2:
|
|
403
|
+
text = "The firmware update has failed. Please try again."
|
|
404
|
+
self.btnUpdate.setEnabled(True)
|
|
405
|
+
self.btnClose.setEnabled(True)
|
|
406
|
+
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok)
|
|
407
|
+
answer = msgbox.exec()
|
|
408
|
+
return False
|
|
409
|
+
elif ret == 3:
|
|
410
|
+
text = "The firmware update file is corrupted. Please re-install the application."
|
|
411
|
+
self.btnUpdate.setEnabled(True)
|
|
412
|
+
self.btnClose.setEnabled(True)
|
|
413
|
+
msgbox = QtWidgets.QMessageBox(parent=self, icon=QtWidgets.QMessageBox.Critical, windowTitle="FlashGBX", text=text, standardButtons=QtWidgets.QMessageBox.Ok)
|
|
414
|
+
answer = msgbox.exec()
|
|
415
|
+
return False
|
|
416
|
+
|
|
417
|
+
def SetStatus(self, text, enableUI=False, setProgress=None):
|
|
418
|
+
self.lblStatus.setText("Status: {:s}".format(text))
|
|
419
|
+
if setProgress is not None:
|
|
420
|
+
self.prgStatus.setValue(setProgress * 10)
|
|
421
|
+
if enableUI:
|
|
422
|
+
self.btnUpdate.setEnabled(True)
|
|
423
|
+
self.btnClose.setEnabled(True)
|
|
424
|
+
self.APP.QT_APP.processEvents()
|
|
425
|
+
except ImportError:
|
|
426
|
+
pass
|
FlashGBX/fw_GBxCartRW_v1_3.py
CHANGED
|
@@ -295,7 +295,7 @@ class FirmwareUpdaterWindow(QtWidgets.QDialog):
|
|
|
295
295
|
lives = 10
|
|
296
296
|
buffer = bytearray()
|
|
297
297
|
|
|
298
|
-
msgWarnBadResponse = "Failed to update your GBxCart RW {:s} ({:s})!\n\nThe firmware update failed as the device is not responding correctly. Please ensure you use a <a href=\"https://www.gbxcart.com/\">genuine GBxCart RW</a>, re-connect using a different USB cable and try again.\n\n⚠️
|
|
298
|
+
msgWarnBadResponse = "Failed to update your GBxCart RW {:s} ({:s})!\n\nThe firmware update failed as the device is not responding correctly. Please ensure you use a <a href=\"https://www.gbxcart.com/\">genuine GBxCart RW</a>, re-connect using a different USB cable and try again.\n\n⚠️ Please note that FlashGBX does not work with the “FLASH BOY” series devices.".format(self.PCB_VER, self.FW_VER).replace("\n", "<br>")
|
|
299
299
|
|
|
300
300
|
fncSetStatus(text="Status: Waiting for bootloader...", setProgress=0)
|
|
301
301
|
if self.ResetAVR(delay) is False:
|