Skip to content

Commit

Permalink
Fix autodetect (betaflight#3667)
Browse files Browse the repository at this point in the history
  • Loading branch information
haslinghuis authored and chmelevskij committed Apr 27, 2024
1 parent d35c252 commit b37422c
Showing 1 changed file with 165 additions and 155 deletions.
320 changes: 165 additions & 155 deletions src/js/tabs/firmware_flasher.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ const firmware_flasher = {
selectedBoard: undefined,
boardNeedsVerification: false,
allowBoardDetection: true,
isFirstRun: true,
isFlashing: false,
intel_hex: undefined, // standard intel hex in string format
parsed_hex: undefined, // parsed raw hex in array format
Expand Down Expand Up @@ -70,10 +69,6 @@ firmware_flasher.initialize = function (callback) {
);
}

function buildKeyExists() {
return FC.CONFIG.buildKey.length === 32;
}

function parseHex(str, callback) {
// parsing hex in different thread
const worker = new Worker('./js/workers/hex_parser.js');
Expand Down Expand Up @@ -221,7 +216,7 @@ firmware_flasher.initialize = function (callback) {
buildOptionsList($('select[name="telemetryProtocols"]'), data.telemetryProtocols);
buildOptionsList($('select[name="options"]'), data.generalOptions);
buildOptionsList($('select[name="motorProtocols"]'), data.motorProtocols);
if (!buildKeyExists()) {
if (!self.buildKeyExists()) {
preselectRadioProtocolFromStorage();
}
}
Expand Down Expand Up @@ -377,7 +372,7 @@ firmware_flasher.initialize = function (callback) {

self.releaseLoader.loadTarget(target, release, onTargetDetail);

if (buildKeyExists() && navigator.onLine) {
if (self.buildKeyExists() && navigator.onLine) {
self.releaseLoader.loadOptionsByBuildKey(release, FC.CONFIG.buildKey, buildOptions);
} else {
self.releaseLoader.loadOptions(release, buildOptions);
Expand Down Expand Up @@ -597,148 +592,6 @@ firmware_flasher.initialize = function (callback) {
self.isFlashing = false;
}

function verifyBoard() {
if (!$('option:selected', portPickerElement).data().isDFU) {

let mspHelper;

function onFinishClose() {
MSP.clearListeners();
MSP.disconnect_cleanup();
}

function onClose(success) {
if (!success) {
gui_log(i18n.getMessage('firmwareFlasherBoardVerificationFail'));
}

serial.disconnect(onFinishClose);
}

function onFinish() {
const board = FC.CONFIG.boardName;
const boardSelect = $('select[name="board"]');
const boardSelectOptions = $('select[name="board"] option');
const target = boardSelect.val();
let targetAvailable = false;

if (board) {
boardSelectOptions.each((_, e) => {
if ($(e).text() === board) {
targetAvailable = true;
}
});

if (board !== target) {
boardSelect.val(board).trigger('change');
}

gui_log(i18n.getMessage(targetAvailable ? 'firmwareFlasherBoardVerificationSuccess' : 'firmwareFlasherBoardVerficationTargetNotAvailable',
{ boardName: board }));
onClose(true);
} else {
onClose(false);
}
}

function getBoardInfo() {
MSP.send_message(MSPCodes.MSP_BOARD_INFO, false, false, onFinish);
}

function getBuildInfo() {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_45) && navigator.onLine && FC.CONFIG.flightControllerIdentifier === 'BTFL') {

function onLoadCloudBuild(options) {
FC.CONFIG.buildOptions = options.Request.Options;
getBoardInfo();
}

MSP.send_message(MSPCodes.MSP2_GET_TEXT, mspHelper.crunch(MSPCodes.MSP2_GET_TEXT, MSPCodes.BUILD_KEY), false, () => {
MSP.send_message(MSPCodes.MSP2_GET_TEXT, mspHelper.crunch(MSPCodes.MSP2_GET_TEXT, MSPCodes.CRAFT_NAME), false, () => {
if (buildKeyExists()) {
self.releaseLoader.requestBuildOptions(FC.CONFIG.buildKey, onLoadCloudBuild, getBoardInfo);
} else {
getBoardInfo();
}
});
});
} else {
getBoardInfo();
}
}

function detectBoard() {
console.log(`Requesting board information`);
MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, () => {
gui_log(i18n.getMessage('apiVersionReceived', FC.CONFIG.apiVersion));

if (FC.CONFIG.apiVersion.includes('null') || semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_39)) {
onClose(false); // not supported
} else {
MSP.send_message(MSPCodes.MSP_FC_VARIANT, false, false, getBuildInfo);
}
});
}

function onConnect(openInfo) {
if (openInfo) {
serial.onReceive.addListener(data => MSP.read(data));
mspHelper = new MspHelper();
MSP.listen(mspHelper.process_data.bind(mspHelper));
detectBoard();
} else {
gui_log(i18n.getMessage('serialPortOpenFail'));
}
}

// Can only verify if not in DFU mode.
if (String(portPickerElement.val()) !== '0') {
const port = String(portPickerElement.val());
let baud = 115200;

if ($('input.flash_manual_baud').is(':checked')) {
baud = parseInt($('#flash_manual_baud_rate').val());
}

gui_log(i18n.getMessage('firmwareFlasherDetectBoardQuery'));

const isLoaded = self.targets ? Object.keys(self.targets).length > 0 : false;

if (isLoaded) {
if (!(serial.connected || serial.connectionId)) {
serial.connect(port, {bitrate: baud}, onConnect);
} else {
console.warn('Attempting to connect while there still is a connection', serial.connected, serial.connectionId, serial.openCanceled);
}
} else {
console.log('Releases not loaded yet');
}
} else {
gui_log(i18n.getMessage('firmwareFlasherNoValidPort'));
}
}
}

const detectBoardElement = $('a.detect-board');

detectBoardElement.on('click', () => {
detectBoardElement.addClass('disabled');

verifyBoard();

setTimeout(() => detectBoardElement.removeClass('disabled'), 1000);
});

function updateDetectBoardButton() {
const isDfu = PortHandler.dfu_available;
const isBusy = GUI.connect_lock;
const isAvailable = PortHandler.port_available || self.isFirstRun;
const isButtonDisabled = isDfu || isBusy || !isAvailable;

detectBoardElement.toggleClass('disabled', isButtonDisabled);
self.isFirstRun = false;
}

let result = getConfig('erase_chip');
if (result.erase_chip) {
$('input.erase_chip').prop('checked', true);
Expand Down Expand Up @@ -1067,7 +920,7 @@ firmware_flasher.initialize = function (callback) {
if (self.boardNeedsVerification) {
// reset to prevent multiple calls
self.boardNeedsVerification = false;
verifyBoard();
self.verifyBoard();
}
if (self.selectedBoard) {
self.enableLoadRemoteFileButton(true);
Expand All @@ -1077,10 +930,19 @@ firmware_flasher.initialize = function (callback) {
self.enableDfuExitButton(false);
}
}
updateDetectBoardButton();
self.updateDetectBoardButton();
}
}).trigger('change');

const detectBoardElement = $('a.detect-board');

detectBoardElement.on('click', () => {
detectBoardElement.addClass('disabled');

self.verifyBoard();
setTimeout(() => detectBoardElement.removeClass('disabled'), 1000);
});

$('a.flash_firmware').on('click', function () {
self.isFlashing = true;

Expand All @@ -1097,8 +959,8 @@ firmware_flasher.initialize = function (callback) {
}
}

// Backup not available in DFU mode
if (!$('option:selected', portPickerElement).data().isDFU) {
// Backup not available in DFU, manual or virtual mode.
if (self.isSerialPortAvailable()) {
GUI.showYesNoDialog(
{
title: i18n.getMessage('firmwareFlasherRemindBackupTitle'),
Expand Down Expand Up @@ -1289,6 +1151,153 @@ firmware_flasher.initialize = function (callback) {
});
};


// Helper functions


firmware_flasher.isSerialPortAvailable = function() {
const selected_port = $('div#port-picker #port option:selected');
const isBusy = GUI.connect_lock;
const isDfu = PortHandler.dfu_available;
const isManual = selected_port.data().isManual || false;
const isVirtual = selected_port.data().isVirtual || false;

return !isDfu && !isManual && !isVirtual && !isBusy;
};

firmware_flasher.updateDetectBoardButton = function() {
$('a.detect-board').toggleClass('disabled', !this.isSerialPortAvailable());
};

firmware_flasher.buildKeyExists = function() {
return FC.CONFIG.buildKey.length === 32;
};

/**
*
* Auto-detect board and set the dropdown to the correct value
*/
firmware_flasher.verifyBoard = function() {
const self = this;

if (!self.isSerialPortAvailable()) {
gui_log(i18n.getMessage('firmwareFlasherNoValidPort'));
return;
}

function onClose(success) {
if (!success) {
gui_log(i18n.getMessage('firmwareFlasherBoardVerificationFail'));
}

serial.disconnect(function () {
MSP.clearListeners();
MSP.disconnect_cleanup();
});
}

function onFinish() {
const board = FC.CONFIG.boardName;
const boardSelect = $('select[name="board"]');
const boardSelectOptions = $('select[name="board"] option');
const target = boardSelect.val();
let targetAvailable = false;

if (board) {
boardSelectOptions.each((_, e) => {
if ($(e).text() === board) {
targetAvailable = true;
}
});

if (board !== target) {
boardSelect.val(board).trigger('change');
}

gui_log(i18n.getMessage(targetAvailable ? 'firmwareFlasherBoardVerificationSuccess' : 'firmwareFlasherBoardVerficationTargetNotAvailable',
{ boardName: board }));
onClose(true);
} else {
onClose(false);
}
}

function requestBoardInformation(onSucces, onFail) {
MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, () => {
gui_log(i18n.getMessage('apiVersionReceived', FC.CONFIG.apiVersion));

if (FC.CONFIG.apiVersion.includes('null') || semver.lt(FC.CONFIG.apiVersion, API_VERSION_1_39)) {
onFail(); // not supported
} else {
MSP.send_message(MSPCodes.MSP_FC_VARIANT, false, false, onSucces);
}
});
}

function getBoardInfo() {
MSP.send_message(MSPCodes.MSP_BOARD_INFO, false, false, onFinish);
}

function getCloudBuildOptions(options) {
FC.CONFIG.buildOptions = options.Request.Options;
getBoardInfo();
}

function getBuildInfo() {
if (semver.gte(FC.CONFIG.apiVersion, API_VERSION_1_45) && navigator.onLine && FC.CONFIG.flightControllerIdentifier === 'BTFL') {
MSP.send_message(MSPCodes.MSP2_GET_TEXT, mspHelper.crunch(MSPCodes.MSP2_GET_TEXT, MSPCodes.BUILD_KEY), false, () => {
MSP.send_message(MSPCodes.MSP2_GET_TEXT, mspHelper.crunch(MSPCodes.MSP2_GET_TEXT, MSPCodes.CRAFT_NAME), false, () => {
if (self.buildKeyExists()) {
self.releaseLoader.requestBuildOptions(FC.CONFIG.buildKey, getCloudBuildOptions, getBoardInfo);
} else {
getBoardInfo();
}
});
});
} else {
getBoardInfo();
}
}

function onConnect(openInfo) {
if (openInfo) {
serial.onReceive.addListener(data => MSP.read(data));
mspHelper = new MspHelper();
MSP.listen(mspHelper.process_data.bind(mspHelper));
requestBoardInformation(getBuildInfo, onClose);
} else {
gui_log(i18n.getMessage('serialPortOpenFail'));
}
}

let mspHelper;
const port = String($('div#port-picker #port').val());
const baud = $('input.flash_manual_baud').is(':checked') ? parseInt($('#flash_manual_baud_rate').val()) : 115200;
const isLoaded = self.targets ? Object.keys(self.targets).length > 0 : false;

if (!isLoaded) {
console.log('Releases not loaded yet');
gui_log(i18n.getMessage('firmwareFlasherNoTargetsLoaded'));
return;
}

if (!(serial.connected || serial.connectionId)) {
gui_log(i18n.getMessage('firmwareFlasherDetectBoardQuery'));
serial.connect(port, {bitrate: baud}, onConnect);
} else {
console.warn('Attempting to connect while there still is a connection', serial.connected, serial.connectionId, serial.openCanceled);
}
};

firmware_flasher.getPort = function () {
return String($('div#port-picker #port').val());
};

/**
*
* Bacup the current configuration to a file before flashing in serial mode
*/

firmware_flasher.backupConfig = function (callback) {
let mspHelper;
let cliBuffer = '';
Expand Down Expand Up @@ -1443,8 +1452,7 @@ firmware_flasher.backupConfig = function (callback) {
}
}

const portPickerElement = $('div#port-picker #port');
const port = String(portPickerElement.val());
const port = this.getPort();

if (port !== '0') {
const baud = parseInt($('#flash_manual_baud_rate').val()) || 115200;
Expand All @@ -1454,6 +1462,8 @@ firmware_flasher.backupConfig = function (callback) {
}
};



firmware_flasher.cleanup = function (callback) {
PortHandler.flush_callbacks();

Expand Down

0 comments on commit b37422c

Please sign in to comment.