diff --git a/locales/en/messages.json b/locales/en/messages.json
index ef0fa052..c29bba7b 100644
--- a/locales/en/messages.json
+++ b/locales/en/messages.json
@@ -9,12 +9,21 @@
"error": {
"message": "Error: {{errorMessage}}"
},
+ "errorTitle": {
+ "message": "Error"
+ },
"warningTitle": {
"message": "Warning"
},
"noticeTitle": {
"message": "Notice"
},
+ "operationNotSupported": {
+ "message": "This operation is not supported by your hardware."
+ },
+ "storageDeviceNotReady": {
+ "message": "The storage device is not ready. In the case of a microSD card, make sure it is properly recognised by your flight controller."
+ },
"options_title": {
"message": "Application Options"
},
@@ -598,8 +607,14 @@
"initialSetupButtonRestore": {
"message": "Restore"
},
+ "initialSetupButtonRebootBootloader": {
+ "message": "Activate Boot Loader / DFU"
+ },
"initialSetupBackupRestoreText": {
- "message": "Backup your configuration in case of an accident, CLI settings are not included - See 'dump' cli command"
+ "message": "Backup your configuration in case of an accident, CLI settings are not included - use the command 'diff all' in CLI for this."
+ },
+ "initialSetupRebootBootloaderText": {
+ "message": "Reboot into boot loader / DFU mode."
},
"initialSetupBackupSuccess": {
"message": "Backup saved successfully"
@@ -3576,6 +3591,18 @@
"onboardLoggingOnboardSDCard": {
"message": "Onboard SD card"
},
+ "onboardLoggingMsc": {
+ "message": "Mass Storage Mode"
+ },
+ "onboardLoggingMscNote": {
+ "message": "Reboot into mass storage device (MSC) mode. Once activated, the onboard flash or SD card on your flight controller will be recognised as a storage device by your computer, and allow you to download your log files. Eject and power cycel your flight controller to leave mass storage device mode."
+ },
+ "onboardLoggingRebootMscText": {
+ "message": "Activate Mass Storage Device Mode"
+ },
+ "onboardLoggingMscNotReady": {
+ "message": "Mass storage mode can not be activated because the storage device is not ready."
+ },
"dialogConfirmResetTitle": {
"message": "Confirm"
},
diff --git a/src/css/tabs/onboard_logging.css b/src/css/tabs/onboard_logging.css
index 87d48452..11e5b431 100644
--- a/src/css/tabs/onboard_logging.css
+++ b/src/css/tabs/onboard_logging.css
@@ -206,6 +206,22 @@
display: none;
}
+.require-msc-supported {
+ display: none;
+}
+
+.tab-onboard_logging.msc-supported .require-msc-supported {
+ display: block;
+}
+
+.require-msc-not-ready {
+ display: none;
+}
+
+.tab-onboard_logging.msc-not-ready .require-msc-not-ready {
+ display: block;
+}
+
@media only screen and (max-width: 1055px) , only screen and (max-device-width: 1055px) {
.tab-onboard_logging table thead tr:first-child {
font-size: 12px;
@@ -300,4 +316,4 @@
pointer-events: none;
text-shadow: none;
opacity: 0.5;
-}
\ No newline at end of file
+}
diff --git a/src/js/main.js b/src/js/main.js
index 326921c2..9ebe303a 100644
--- a/src/js/main.js
+++ b/src/js/main.js
@@ -642,4 +642,16 @@ function openNewWindowsInExternalBrowser() {
} catch (ex) {
console.log("require does not exist, maybe inside chrome");
}
-}
\ No newline at end of file
+}
+
+function showErrorDialog(message) {
+ var dialog = $('.dialogError')[0];
+
+ $('.dialogError-content').html(message);
+
+ $('.dialogError-closebtn').click(function() {
+ dialog.close();
+ });
+
+ dialog.showModal();
+}
diff --git a/src/js/msp/MSPHelper.js b/src/js/msp/MSPHelper.js
index 4ebe8498..235a3973 100644
--- a/src/js/msp/MSPHelper.js
+++ b/src/js/msp/MSPHelper.js
@@ -27,6 +27,12 @@ function MspHelper () {
'RUNCAM_DEVICE_CONTROL': 14, // support communitate with RunCam Device
'LIDAR_TF': 15
};
+
+ self.REBOOT_TYPES = {
+ FIRMWARE: 0,
+ BOOTLOADER: 1,
+ MSC: 2
+ };
}
MspHelper.prototype.reorderPwmProtocols = function (protocol) {
@@ -617,6 +623,17 @@ MspHelper.prototype.process_data = function(dataHandler) {
break;
case MSPCodes.MSP_SET_REBOOT:
+ if (semver.gte(CONFIG.apiVersion, "1.40.0")) {
+ var rebootType = data.read8();
+ if (rebootType === self.REBOOT_TYPES.MSC) {
+ if (data.read8() === 0) {
+ console.log('Storage device not ready.');
+
+ showErrorDialog(i18n.getMessage('storageDeviceNotReady'));
+ break;
+ }
+ }
+ }
console.log('Reboot request accepted');
break;
@@ -1187,6 +1204,11 @@ MspHelper.prototype.process_data = function(dataHandler) {
console.log('Unknown code detected: ' + code);
} else {
console.log('FC reports unsupported message error: ' + code);
+
+ switch (code) {
+ case MSPCodes.MSP_SET_REBOOT:
+ showErrorDialog(i18n.getMessage('operationNotSupported'));
+ }
}
}
// trigger callbacks, cleanup/remove callback after trigger
@@ -1209,7 +1231,6 @@ MspHelper.prototype.process_data = function(dataHandler) {
}
}
-
/**
* Encode the request body for the MSP request with the given code and return it as an array of bytes.
*/
diff --git a/src/js/tabs/onboard_logging.js b/src/js/tabs/onboard_logging.js
index 68dc1d12..688ab7ca 100644
--- a/src/js/tabs/onboard_logging.js
+++ b/src/js/tabs/onboard_logging.js
@@ -145,6 +145,20 @@ TABS.onboard_logging.initialize = function (callback) {
$("div.blackboxRate").show();
}
}).change();
+
+ if (semver.gte(CONFIG.apiVersion, "1.40.0")) {
+ if (SDCARD.supported || DATAFLASH.supported) {
+
+ $(".tab-onboard_logging")
+ .toggleClass("msc-supported", true);
+
+ $('a.onboardLoggingRebootMsc').click(function () {
+ var buffer = [];
+ buffer.push(2);
+ MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, false);
+ });
+ }
+ }
update_html();
@@ -296,6 +310,18 @@ TABS.onboard_logging.initialize = function (callback) {
.toggleClass("sdcard-error", SDCARD.state === MSP.SDCARD_STATE_FATAL)
.toggleClass("sdcard-initializing", SDCARD.state === MSP.SDCARD_STATE_CARD_INIT || SDCARD.state === MSP.SDCARD_STATE_FS_INIT)
.toggleClass("sdcard-ready", SDCARD.state === MSP.SDCARD_STATE_READY);
+
+ if (semver.gte(CONFIG.apiVersion, "1.40.0")) {
+ var mscIsReady = (DATAFLASH.totalSize > 0) || (SDCARD.state === MSP.SDCARD_STATE_READY);
+ $(".tab-onboard_logging")
+ .toggleClass("msc-not-ready", !mscIsReady);
+
+ if (!mscIsReady) {
+ $('a.onboardLoggingRebootMsc').addClass('disabled');
+ } else {
+ $('a.onboardLoggingRebootMsc').removeClass('disabled');
+ }
+ }
switch (SDCARD.state) {
case MSP.SDCARD_STATE_NOT_PRESENT:
diff --git a/src/js/tabs/setup.js b/src/js/tabs/setup.js
index 686b0698..c3f6663f 100755
--- a/src/js/tabs/setup.js
+++ b/src/js/tabs/setup.js
@@ -59,9 +59,24 @@ TABS.setup.initialize = function (callback) {
self.initializeInstruments();
-
$('#arming-disable-flag-row').attr('title', i18n.getMessage('initialSetupArmingDisableFlagsTooltip'));
+ if (semver.gte(CONFIG.apiVersion, "1.40.0")) {
+ if (isExpertModeEnabled()) {
+ $('.initialSetupRebootBootloader').show();
+ } else {
+ $('.initialSetupRebootBootloader').hide();
+ }
+
+ $('a.rebootBootloader').click(function () {
+ var buffer = [];
+ buffer.push(1);
+ MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, false);
+ });
+ } else {
+ $('.initialSetupRebootBootloader').hide();
+ }
+
// UI Hooks
$('a.calibrateAccel').click(function () {
var self = $(this);
diff --git a/src/main.html b/src/main.html
index cdd9775b..94b1652e 100755
--- a/src/main.html
+++ b/src/main.html
@@ -323,5 +323,15 @@
+
+