Skip to content

Commit f6aba04

Browse files
authored
Fix flash state (#4653)
* Fix flash state * Handle reset state for STM32.connect too * Fix sonar * Fix unhandled promise rejection * CR nitpick * ¯\_(ツ)_/¯ * Remove redundant error handling * Cleaning up * Second time ignoring dialog we are here * Second time ignoring dialog we are here - lets recover here too * Prevent detection without available port * Consolidate error handling in STM32
1 parent 6133a7b commit f6aba04

File tree

3 files changed

+76
-29
lines changed

3 files changed

+76
-29
lines changed

src/js/protocols/webstm32.js

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,9 @@ function readSerialAdapter(event) {
2525
read_serial(event.detail.buffer);
2626
}
2727

28-
function onTimeoutHandler() {
29-
GUI.connect_lock = false;
30-
console.log(`${STM32Protocol.logHead} Looking for capabilities via MSP failed`);
31-
32-
TABS.firmware_flasher.flashingMessage(
33-
i18n.getMessage("stm32RebootingToBootloaderFailed"),
34-
TABS.firmware_flasher.FLASH_MESSAGE_TYPES.INVALID,
35-
);
36-
}
37-
38-
function onFailureHandler() {
39-
GUI.connect_lock = false;
40-
TABS.firmware_flasher.refresh();
28+
function onMSPConnectionError() {
29+
gui_log(i18n.getMessage("stm32RebootingToBootloaderFailed"));
30+
STM32.handleError();
4131
}
4232

4333
class STM32Protocol {
@@ -88,6 +78,18 @@ class STM32Protocol {
8878
this.handleMSPConnect = this.handleMSPConnect.bind(this);
8979
}
9080

81+
/**
82+
* Centralized error handling method that resets UI state and releases connection lock
83+
* @param {boolean} resetRebootMode - Whether to reset the reboot mode
84+
*/
85+
handleError(resetRebootMode = true) {
86+
GUI.connect_lock = false;
87+
if (resetRebootMode) {
88+
this.rebootMode = 0;
89+
}
90+
TABS.firmware_flasher.resetFlashingState();
91+
}
92+
9193
handleConnect(event) {
9294
console.log(`${this.logHead} Connected to serial port`, event.detail, event);
9395
if (event) {
@@ -118,19 +120,17 @@ class STM32Protocol {
118120
console.log(`${this.logHead} DFU request permission granted`, device);
119121
} else {
120122
console.error(`${this.logHead} DFU request permission denied`);
121-
this.rebootMode = 0;
122-
GUI.connect_lock = false;
123+
this.handleError();
123124
}
124125
})
125126
.catch((e) => {
126127
console.error(`${this.logHead} DFU request permission failed`, e);
127-
this.rebootMode = 0;
128-
GUI.connect_lock = false;
128+
this.handleError();
129129
});
130130
}
131131
}, 3000);
132132
} else {
133-
GUI.connect_lock = false;
133+
this.handleError(false);
134134
}
135135
}
136136

@@ -251,8 +251,8 @@ class STM32Protocol {
251251
this.port,
252252
this.mspOptions.reboot_baud,
253253
this.handleMSPConnect,
254-
onTimeoutHandler,
255-
onFailureHandler,
254+
onMSPConnectionError,
255+
onMSPConnectionError,
256256
);
257257
}
258258
}

src/js/tabs/firmware_flasher.js

Lines changed: 51 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@ const firmware_flasher = {
2929
selectedBoard: undefined,
3030
cloudBuildKey: null,
3131
cloudBuildOptions: null,
32-
isFlashing: false,
3332
intel_hex: undefined, // standard intel hex in string format
3433
parsed_hex: undefined, // parsed raw hex in array format
3534
isConfigLocal: false, // Set to true if the user loads one locally
@@ -38,6 +37,9 @@ const firmware_flasher = {
3837
config: {},
3938
developmentFirmwareLoaded: false, // Is the firmware to be flashed from the development branch?
4039
cancelBuild: false,
40+
// Properties to preserve firmware state during flashing
41+
preFlashingMessage: null,
42+
preFlashingMessageType: null,
4143
};
4244

4345
firmware_flasher.initialize = async function (callback) {
@@ -813,12 +815,17 @@ firmware_flasher.initialize = async function (callback) {
813815
} else {
814816
// Maybe the board is in DFU mode, but it does not have permissions. Ask for them.
815817
console.log(`${self.logHead} No valid port detected, asking for permissions`);
816-
DFU.requestPermission().then((device) => {
817-
DFU.connect(device.path, firmware, options);
818-
});
818+
819+
DFU.requestPermission()
820+
.then((device) => {
821+
DFU.connect(device.path, firmware, options);
822+
})
823+
.catch((error) => {
824+
console.error("Permission request failed", error);
825+
firmware_flasher.resetFlashingState();
826+
});
819827
}
820828

821-
self.isFlashing = false;
822829
GUI.interval_resume("sponsor");
823830
}
824831

@@ -1268,7 +1275,6 @@ firmware_flasher.initialize = async function (callback) {
12681275

12691276
const aborted = function (message) {
12701277
GUI.connect_lock = false;
1271-
self.isFlashing = false;
12721278
self.enableFlashButton(true);
12731279
self.enableLoadRemoteFileButton(true);
12741280
self.enableLoadFileButton(true);
@@ -1391,7 +1397,9 @@ firmware_flasher.initialize = async function (callback) {
13911397
return;
13921398
}
13931399

1394-
self.isFlashing = true;
1400+
// Preserve current firmware message state before flashing
1401+
self.preservePreFlashingState();
1402+
13951403
GUI.interval_pause("sponsor");
13961404

13971405
self.enableFlashButton(false);
@@ -1414,7 +1422,6 @@ firmware_flasher.initialize = async function (callback) {
14141422
: i18n.getMessage("firmwareFlasherUF2SaveFailed"),
14151423
saved ? self.FLASH_MESSAGE_TYPES.VALID : self.FLASH_MESSAGE_TYPES.INVALID,
14161424
);
1417-
self.isFlashing = false;
14181425
GUI.interval_resume("sponsor");
14191426
self.enableFlashButton(true);
14201427
self.enableLoadRemoteFileButton(true);
@@ -1510,6 +1517,42 @@ firmware_flasher.enableDfuExitButton = function (enabled) {
15101517
$("a.exit_dfu").toggleClass("disabled", !enabled);
15111518
};
15121519

1520+
firmware_flasher.resetFlashingState = function () {
1521+
console.log(`${this.logHead} Reset flashing state`);
1522+
this.enableFlashButton(!!this.parsed_hex || !!this.uf2_binary); // Only enable if firmware is loaded
1523+
this.enableDfuExitButton(PortHandler.dfuAvailable);
1524+
this.enableLoadRemoteFileButton(true);
1525+
this.enableLoadFileButton(true);
1526+
1527+
// Restore pre-flashing message if firmware is still loaded, otherwise show "not loaded"
1528+
if (this.parsed_hex || this.uf2_binary) {
1529+
if (this.preFlashingMessage && this.preFlashingMessageType) {
1530+
this.flashingMessage(this.preFlashingMessage, this.preFlashingMessageType);
1531+
}
1532+
} else {
1533+
this.flashingMessage(i18n.getMessage("firmwareFlasherFirmwareNotLoaded"), this.FLASH_MESSAGE_TYPES.NEUTRAL);
1534+
}
1535+
1536+
GUI.interval_resume("sponsor");
1537+
};
1538+
1539+
firmware_flasher.preservePreFlashingState = function () {
1540+
// Preserve the current firmware message and type before flashing starts
1541+
const progressLabel = $("span.progressLabel");
1542+
this.preFlashingMessage = progressLabel.html();
1543+
1544+
// Determine the current message type based on CSS classes
1545+
if (progressLabel.hasClass("valid")) {
1546+
this.preFlashingMessageType = this.FLASH_MESSAGE_TYPES.VALID;
1547+
} else if (progressLabel.hasClass("invalid")) {
1548+
this.preFlashingMessageType = this.FLASH_MESSAGE_TYPES.INVALID;
1549+
} else if (progressLabel.hasClass("actionRequired")) {
1550+
this.preFlashingMessageType = this.FLASH_MESSAGE_TYPES.ACTION;
1551+
} else {
1552+
this.preFlashingMessageType = this.FLASH_MESSAGE_TYPES.NEUTRAL;
1553+
}
1554+
};
1555+
15131556
firmware_flasher.refresh = function (callback) {
15141557
const self = this;
15151558

src/js/utils/AutoDetect.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,12 @@ class AutoDetect {
3737
const port = PortHandler.portPicker.selectedPort;
3838
const isLoaded = TABS.firmware_flasher.targets ? Object.keys(TABS.firmware_flasher.targets).length > 0 : false;
3939

40+
if (!PortHandler.portAvailable) {
41+
gui_log(i18n.getMessage("firmwareFlasherNoValidPort"));
42+
return;
43+
}
44+
4045
if (!isLoaded) {
41-
console.log("Releases not loaded yet");
4246
gui_log(i18n.getMessage("firmwareFlasherNoTargetsLoaded"));
4347
return;
4448
}

0 commit comments

Comments
 (0)