Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix autodetect #3667

Merged
merged 1 commit into from Dec 11, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
320 changes: 165 additions & 155 deletions src/js/tabs/firmware_flasher.js
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