Merge pull request #1582 from hydra/support-reboot-to-flash-bootloader
Replace legacy firmware reboot sequence with MSP based sequence.10.7.0-preview
commit
c77fe48be9
|
@ -217,6 +217,12 @@
|
||||||
"deviceRebooting": {
|
"deviceRebooting": {
|
||||||
"message": "Device - <span class=\"message-negative\">Rebooting</span>"
|
"message": "Device - <span class=\"message-negative\">Rebooting</span>"
|
||||||
},
|
},
|
||||||
|
"deviceRebooting_flashBootloader": {
|
||||||
|
"message": "Device - <span class=\"message-negative\">Rebooting to FLASH BOOTLOADER</span>"
|
||||||
|
},
|
||||||
|
"deviceRebooting_romBootloader": {
|
||||||
|
"message": "Device - <span class=\"message-negative\">Rebooting to ROM BOOTLOADER</span>"
|
||||||
|
},
|
||||||
"deviceReady": {
|
"deviceReady": {
|
||||||
"message": "Device - <span class=\"message-positive\">Ready</span>"
|
"message": "Device - <span class=\"message-positive\">Ready</span>"
|
||||||
},
|
},
|
||||||
|
@ -370,6 +376,12 @@
|
||||||
"stm32UsbDfuNotFound": {
|
"stm32UsbDfuNotFound": {
|
||||||
"message": "USB DFU not found"
|
"message": "USB DFU not found"
|
||||||
},
|
},
|
||||||
|
"stm32RebootingToBootloader": {
|
||||||
|
"message": "Initiating reboot to bootloader ..."
|
||||||
|
},
|
||||||
|
"stm32RebootingToBootloaderFailed": {
|
||||||
|
"message": "Rebooting device to bootloader: FAILED"
|
||||||
|
},
|
||||||
"stm32TimedOut": {
|
"stm32TimedOut": {
|
||||||
"message": "STM32 - timed out, programming: FAILED"
|
"message": "STM32 - timed out, programming: FAILED"
|
||||||
},
|
},
|
||||||
|
|
|
@ -0,0 +1,78 @@
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
var MSPConnectorImpl = function () {
|
||||||
|
this.baud = undefined;
|
||||||
|
this.port = undefined;
|
||||||
|
this.onConnectCallback = undefined;
|
||||||
|
this.onTimeoutCallback = undefined;
|
||||||
|
this.onDisconnectCallback = undefined;
|
||||||
|
};
|
||||||
|
|
||||||
|
MSPConnectorImpl.prototype.connect = function (port, baud, onConnectCallback, onTimeoutCallback, onFailureCallback) {
|
||||||
|
|
||||||
|
var self = this;
|
||||||
|
self.port = port;
|
||||||
|
self.baud = baud;
|
||||||
|
self.onConnectCallback = onConnectCallback;
|
||||||
|
self.onTimeoutCallback = onTimeoutCallback;
|
||||||
|
self.onFailureCallback = onFailureCallback;
|
||||||
|
|
||||||
|
serial.connect(self.port, {bitrate: self.baud}, function (openInfo) {
|
||||||
|
if (openInfo) {
|
||||||
|
var disconnectAndCleanup = function() {
|
||||||
|
serial.disconnect(function(result) {
|
||||||
|
console.log('Disconnected');
|
||||||
|
|
||||||
|
MSP.clearListeners();
|
||||||
|
|
||||||
|
self.onTimeoutCallback();
|
||||||
|
});
|
||||||
|
|
||||||
|
MSP.disconnect_cleanup();
|
||||||
|
};
|
||||||
|
|
||||||
|
FC.resetState();
|
||||||
|
|
||||||
|
// disconnect after 10 seconds with error if we don't get IDENT data
|
||||||
|
GUI.timeout_add('msp_connector', function () {
|
||||||
|
if (!CONFIGURATOR.connectionValid) {
|
||||||
|
GUI.log(i18n.getMessage('noConfigurationReceived'));
|
||||||
|
|
||||||
|
disconnectAndCleanup();
|
||||||
|
}
|
||||||
|
}, 10000);
|
||||||
|
|
||||||
|
serial.onReceive.addListener(read_serial);
|
||||||
|
|
||||||
|
MSP.listen(update_packet_error);
|
||||||
|
mspHelper = new MspHelper();
|
||||||
|
MSP.listen(mspHelper.process_data.bind(mspHelper));
|
||||||
|
|
||||||
|
MSP.send_message(MSPCodes.MSP_API_VERSION, false, false, function () {
|
||||||
|
CONFIGURATOR.connectionValid = true;
|
||||||
|
|
||||||
|
GUI.timeout_remove('msp_connector');
|
||||||
|
console.log('Connected');
|
||||||
|
|
||||||
|
self.onConnectCallback();
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
GUI.log(i18n.getMessage('serialPortOpenFail'));
|
||||||
|
self.onFailureCallback();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
MSPConnectorImpl.prototype.disconnect = function(onDisconnectCallback) {
|
||||||
|
self.onDisconnectCallback = onDisconnectCallback;
|
||||||
|
|
||||||
|
serial.disconnect(function (result) {
|
||||||
|
MSP.clearListeners();
|
||||||
|
console.log('Disconnected');
|
||||||
|
|
||||||
|
self.onDisconnectCallback(result);
|
||||||
|
});
|
||||||
|
|
||||||
|
MSP.disconnect_cleanup();
|
||||||
|
};
|
||||||
|
|
|
@ -22,6 +22,8 @@ var STM32_protocol = function () {
|
||||||
this.upload_time_start;
|
this.upload_time_start;
|
||||||
this.upload_process_alive;
|
this.upload_process_alive;
|
||||||
|
|
||||||
|
this.msp_connector = new MSPConnectorImpl();
|
||||||
|
|
||||||
this.status = {
|
this.status = {
|
||||||
ACK: 0x79, // y
|
ACK: 0x79, // y
|
||||||
NACK: 0x1F
|
NACK: 0x1F
|
||||||
|
@ -53,6 +55,7 @@ var STM32_protocol = function () {
|
||||||
STM32_protocol.prototype.connect = function (port, baud, hex, options, callback) {
|
STM32_protocol.prototype.connect = function (port, baud, hex, options, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.hex = hex;
|
self.hex = hex;
|
||||||
|
self.port = port;
|
||||||
self.baud = baud;
|
self.baud = baud;
|
||||||
self.callback = callback;
|
self.callback = callback;
|
||||||
|
|
||||||
|
@ -85,30 +88,14 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options, callback)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
serial.connect(port, {bitrate: self.options.reboot_baud}, function (openInfo) {
|
|
||||||
if (openInfo) {
|
|
||||||
console.log('Sending ascii "R" to reboot');
|
|
||||||
|
|
||||||
// we are connected, disabling connect button in the UI
|
var startFlashing = function() {
|
||||||
GUI.connect_lock = true;
|
|
||||||
|
|
||||||
var bufferOut = new ArrayBuffer(1);
|
|
||||||
var bufferView = new Uint8Array(bufferOut);
|
|
||||||
|
|
||||||
bufferView[0] = 0x52;
|
|
||||||
|
|
||||||
serial.send(bufferOut, function () {
|
|
||||||
serial.disconnect(function (result) {
|
|
||||||
if (result) {
|
|
||||||
// delay to allow board to boot in bootloader mode
|
|
||||||
// required to detect if a DFU device appears
|
|
||||||
setTimeout(function() {
|
|
||||||
// refresh device list
|
// refresh device list
|
||||||
PortHandler.check_usb_devices(function(dfu_available) {
|
PortHandler.check_usb_devices(function(dfu_available) {
|
||||||
if(dfu_available) {
|
if(dfu_available) {
|
||||||
STM32DFU.connect(usbDevices, hex, options);
|
STM32DFU.connect(usbDevices, hex, options);
|
||||||
} else {
|
} else {
|
||||||
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
|
serial.connect(self.port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
|
||||||
if (openInfo) {
|
if (openInfo) {
|
||||||
self.initialize();
|
self.initialize();
|
||||||
} else {
|
} else {
|
||||||
|
@ -118,16 +105,103 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options, callback)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, 1000);
|
};
|
||||||
|
|
||||||
|
var legacyRebootAndFlash = function() {
|
||||||
|
serial.connect(self.port, {bitrate: self.options.reboot_baud}, function (openInfo) {
|
||||||
|
if (!openInfo) {
|
||||||
|
GUI.connect_lock = false;
|
||||||
|
GUI.log(i18n.getMessage('serialPortOpenFail'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('Using legacy reboot method');
|
||||||
|
|
||||||
|
console.log('Sending ascii "R" to reboot');
|
||||||
|
var bufferOut = new ArrayBuffer(1);
|
||||||
|
var bufferView = new Uint8Array(bufferOut);
|
||||||
|
|
||||||
|
bufferView[0] = 0x52;
|
||||||
|
|
||||||
|
serial.send(bufferOut, function () {
|
||||||
|
serial.disconnect(function (disconnectionResult) {
|
||||||
|
if (disconnectionResult) {
|
||||||
|
// delay to allow board to boot in bootloader mode
|
||||||
|
// required to detect if a DFU device appears
|
||||||
|
setTimeout(startFlashing, 1000);
|
||||||
} else {
|
} else {
|
||||||
GUI.connect_lock = false;
|
GUI.connect_lock = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
var onConnectHandler = function () {
|
||||||
|
|
||||||
|
GUI.log(i18n.getMessage('apiVersionReceived', [CONFIG.apiVersion]));
|
||||||
|
|
||||||
|
if (semver.lt(CONFIG.apiVersion, "1.42.0")) {
|
||||||
|
|
||||||
|
self.msp_connector.disconnect(function (disconnectionResult) {
|
||||||
|
|
||||||
|
// need some time for the port to be closed, serial port does not open if tried immediately
|
||||||
|
setTimeout(legacyRebootAndFlash, 500);
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
GUI.log(i18n.getMessage('serialPortOpenFail'));
|
console.log('Looking for capabilities via MSP');
|
||||||
|
|
||||||
|
MSP.send_message(MSPCodes.MSP_BOARD_INFO, false, false, function () {
|
||||||
|
var rebootMode = 0; // FIRMWARE
|
||||||
|
if (bit_check(CONFIG.commCapabilities, 3)) {
|
||||||
|
// Board has flash bootloader
|
||||||
|
GUI.log(i18n.getMessage('deviceRebooting_flashBootloader'));
|
||||||
|
console.log('flash bootloader detected');
|
||||||
|
rebootMode = 4; // MSP_REBOOT_BOOTLOADER_FLASH
|
||||||
|
} else {
|
||||||
|
GUI.log(i18n.getMessage('deviceRebooting_romBootloader'));
|
||||||
|
console.log('no flash bootloader detected');
|
||||||
|
rebootMode = 1; // MSP_REBOOT_BOOTLOADER_ROM;
|
||||||
|
}
|
||||||
|
|
||||||
|
var buffer = [];
|
||||||
|
buffer.push8(rebootMode);
|
||||||
|
MSP.send_message(MSPCodes.MSP_SET_REBOOT, buffer, function() {
|
||||||
|
|
||||||
|
// if firmware doesn't flush MSP/serial send buffers and gracefully shutdown VCP connections we won't get a reply, so don't wait for it.
|
||||||
|
|
||||||
|
self.msp_connector.disconnect(function (disconnectionResult) {
|
||||||
|
if (disconnectionResult) {
|
||||||
|
// delay to allow board to boot in bootloader mode
|
||||||
|
// required to detect if a DFU device appears
|
||||||
|
setTimeout(startFlashing, 1000);
|
||||||
|
} else {
|
||||||
|
GUI.connect_lock = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
}, function () {
|
||||||
|
console.log('Reboot request recevied by device');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var onTimeoutHandler = function() {
|
||||||
|
GUI.connect_lock = false;
|
||||||
|
console.log('Looking for capabilities via MSP failed');
|
||||||
|
|
||||||
|
TABS.firmware_flasher.flashingMessage(i18n.getMessage('stm32RebootingToBootloaderFailed'), TABS.firmware_flasher.FLASH_MESSAGE_TYPES.INVALID);
|
||||||
|
}
|
||||||
|
|
||||||
|
var onFailureHandler = function() {
|
||||||
|
GUI.connect_lock = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
GUI.connect_lock = true;
|
||||||
|
TABS.firmware_flasher.flashingMessage(i18n.getMessage('stm32RebootingToBootloader'), TABS.firmware_flasher.FLASH_MESSAGE_TYPES.NEUTRAL);
|
||||||
|
|
||||||
|
self.msp_connector.connect(self.port, self.options.reboot_baud, onConnectHandler, onTimeoutHandler, onFailureHandler);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -125,6 +125,7 @@
|
||||||
<script type="text/javascript" src="./js/model.js"></script>
|
<script type="text/javascript" src="./js/model.js"></script>
|
||||||
<script type="text/javascript" src="./js/serial_backend.js"></script>
|
<script type="text/javascript" src="./js/serial_backend.js"></script>
|
||||||
<script type="text/javascript" src="./js/msp/MSPCodes.js"></script>
|
<script type="text/javascript" src="./js/msp/MSPCodes.js"></script>
|
||||||
|
<script type="text/javascript" src="./js/msp/MSPConnector.js"></script>
|
||||||
<script type="text/javascript" src="./js/msp.js"></script>
|
<script type="text/javascript" src="./js/msp.js"></script>
|
||||||
<script type="text/javascript" src="./js/msp/MSPHelper.js"></script>
|
<script type="text/javascript" src="./js/msp/MSPHelper.js"></script>
|
||||||
<script type="text/javascript" src="./js/backup_restore.js"></script>
|
<script type="text/javascript" src="./js/backup_restore.js"></script>
|
||||||
|
|
Loading…
Reference in New Issue