DFU: Add local erase, 2 kB page size hardcoded
Not possible to read chip ID using DFU or page size info from USB descriptor (not yet supported by Chrome)10.3.x-maintenance
parent
d89e9682c2
commit
1e386f508b
|
@ -107,7 +107,7 @@ STM32_protocol.prototype.connect = function (port, baud, hex, options, callback)
|
||||||
PortHandler.check_usb_devices(function(dfu_available) {
|
PortHandler.check_usb_devices(function(dfu_available) {
|
||||||
if(dfu_available) {
|
if(dfu_available) {
|
||||||
GUI.connect_lock = false;
|
GUI.connect_lock = false;
|
||||||
STM32DFU.connect(usbDevices.STM32DFU, hex);
|
STM32DFU.connect(usbDevices.STM32DFU, hex, options);
|
||||||
} else {
|
} else {
|
||||||
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
|
serial.connect(port, {bitrate: self.baud, parityBit: 'even', stopBits: 'one'}, function (openInfo) {
|
||||||
if (openInfo) {
|
if (openInfo) {
|
||||||
|
|
|
@ -61,13 +61,26 @@ var STM32DFU_protocol = function () {
|
||||||
dfuUPLOAD_IDLE: 9, // The device is processing an upload operation. Expecting DFU_UPLOAD requests.
|
dfuUPLOAD_IDLE: 9, // The device is processing an upload operation. Expecting DFU_UPLOAD requests.
|
||||||
dfuERROR: 10 // An error has occurred. Awaiting the DFU_CLRSTATUS request.
|
dfuERROR: 10 // An error has occurred. Awaiting the DFU_CLRSTATUS request.
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Assume 2 kB page size (STM32F303)
|
||||||
|
// Cannot read chip ID using DFU protocol and Chrome doesn't provide the interface
|
||||||
|
// description string with flash page size information (at least on Linux anyway)
|
||||||
|
this.page_size = 2048;
|
||||||
};
|
};
|
||||||
|
|
||||||
STM32DFU_protocol.prototype.connect = function (device, hex, callback) {
|
STM32DFU_protocol.prototype.connect = function (device, hex, options, callback) {
|
||||||
var self = this;
|
var self = this;
|
||||||
self.hex = hex;
|
self.hex = hex;
|
||||||
self.callback = callback;
|
self.callback = callback;
|
||||||
|
|
||||||
|
self.options = {
|
||||||
|
erase_chip: false
|
||||||
|
};
|
||||||
|
|
||||||
|
if (options.erase_chip) {
|
||||||
|
self.options.erase_chip = true;
|
||||||
|
}
|
||||||
|
|
||||||
// reset and set some variables before we start
|
// reset and set some variables before we start
|
||||||
self.upload_time_start = new Date().getTime();
|
self.upload_time_start = new Date().getTime();
|
||||||
self.verify_hex = [];
|
self.verify_hex = [];
|
||||||
|
@ -150,6 +163,12 @@ STM32DFU_protocol.prototype.controlTransfer = function (direction, request, valu
|
||||||
'index': _interface,
|
'index': _interface,
|
||||||
'length': length
|
'length': length
|
||||||
}, function (result) {
|
}, function (result) {
|
||||||
|
if (chrome.runtime.lastError) {
|
||||||
|
if(chrome.runtime.lastError.message)
|
||||||
|
console.log(chrome.runtime.lastError.message);
|
||||||
|
else
|
||||||
|
console.log(chrome.runtime.lastError);
|
||||||
|
}
|
||||||
if (result.resultCode) console.log(result.resultCode);
|
if (result.resultCode) console.log(result.resultCode);
|
||||||
|
|
||||||
var buf = new Uint8Array(result.data);
|
var buf = new Uint8Array(result.data);
|
||||||
|
@ -217,7 +236,7 @@ STM32DFU_protocol.prototype.loadAddress = function (address, callback) {
|
||||||
if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
||||||
callback(data);
|
callback(data);
|
||||||
} else {
|
} else {
|
||||||
console.log('Failed to execure address load');
|
console.log('Failed to execute address load');
|
||||||
self.upload_procedure(99);
|
self.upload_procedure(99);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -256,32 +275,85 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
// full chip erase
|
// erase
|
||||||
console.log('Executing global chip erase');
|
if (self.options.erase_chip) {
|
||||||
$('span.progressLabel').text('Erasing ...');
|
// full chip erase
|
||||||
|
console.log('Executing global chip erase');
|
||||||
|
$('span.progressLabel').text('Erasing ...');
|
||||||
|
|
||||||
self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x41], function () {
|
self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x41], function () {
|
||||||
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||||
if (data[4] == self.state.dfuDNBUSY) { // completely normal
|
if (data[4] == self.state.dfuDNBUSY) { // completely normal
|
||||||
var delay = data[1] | (data[2] << 8) | (data[3] << 16);
|
var delay = data[1] | (data[2] << 8) | (data[3] << 16);
|
||||||
|
|
||||||
setTimeout(function () {
|
setTimeout(function () {
|
||||||
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||||
if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
||||||
self.upload_procedure(4);
|
self.upload_procedure(4);
|
||||||
} else {
|
} else {
|
||||||
console.log('Failed to execute global chip erase');
|
console.log('Failed to execute global chip erase');
|
||||||
self.upload_procedure(99);
|
self.upload_procedure(99);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, delay);
|
}, delay);
|
||||||
} else {
|
} else {
|
||||||
console.log('Failed to initiate global chip erase');
|
console.log('Failed to initiate global chip erase');
|
||||||
self.upload_procedure(99);
|
self.upload_procedure(99);
|
||||||
}
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
});
|
} else {
|
||||||
|
// local erase
|
||||||
|
|
||||||
|
var max_address = self.hex.data[self.hex.data.length - 1].address + self.hex.data[self.hex.data.length - 1].bytes - 0x8000000,
|
||||||
|
erase_pages_n = Math.ceil(max_address / self.page_size),
|
||||||
|
page = 0;
|
||||||
|
|
||||||
|
$('span.progressLabel').text('Erasing ...');
|
||||||
|
console.log('Executing local chip erase');
|
||||||
|
console.log('Erasing. page: 0x00 - 0x' + erase_pages_n.toString(16));
|
||||||
|
|
||||||
|
var erase_page = function() {
|
||||||
|
var page_addr = page * self.page_size + 0x8000000;
|
||||||
|
var cmd = [0x41, page_addr & 0xff, (page_addr >> 8) & 0xff, (page_addr >> 16) & 0xff, (page_addr >> 24) & 0xff];
|
||||||
|
|
||||||
|
self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, cmd, function () {
|
||||||
|
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||||
|
if (data[4] == self.state.dfuDNBUSY) { // completely normal
|
||||||
|
var delay = data[1] | (data[2] << 8) | (data[3] << 16);
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||||
|
if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
||||||
|
// update progress bar
|
||||||
|
self.progress_bar_e.val((page + 1) / erase_pages_n * 100);
|
||||||
|
page++;
|
||||||
|
|
||||||
|
if(page == erase_pages_n) {
|
||||||
|
console.log("Erase: complete");
|
||||||
|
self.upload_procedure(4);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
erase_page();
|
||||||
|
} else {
|
||||||
|
console.log('Failed to erase page 0x' + self.current_page.toString(16));
|
||||||
|
self.upload_procedure(99);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, delay);
|
||||||
|
} else {
|
||||||
|
console.log('Failed to initiate page erase, page 0x' + self.current_page.toString(16));
|
||||||
|
self.upload_procedure(99);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
// start
|
||||||
|
erase_page();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
case 4:
|
||||||
// upload
|
// upload
|
||||||
// we dont need to clear the state as we are already using DFU_DNLOAD
|
// we dont need to clear the state as we are already using DFU_DNLOAD
|
||||||
|
|
|
@ -307,10 +307,15 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
if (!$(this).hasClass('locked')) {
|
if (!$(this).hasClass('locked')) {
|
||||||
if (!GUI.connect_lock) { // button disabled while flashing is in progress
|
if (!GUI.connect_lock) { // button disabled while flashing is in progress
|
||||||
if (parsed_hex != false) {
|
if (parsed_hex != false) {
|
||||||
|
var options = {};
|
||||||
|
|
||||||
|
if ($('input.erase_chip').is(':checked')) {
|
||||||
|
options.erase_chip = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (String($('div#port-picker #port').val()) != 'DFU') {
|
if (String($('div#port-picker #port').val()) != 'DFU') {
|
||||||
if (String($('div#port-picker #port').val()) != '0') {
|
if (String($('div#port-picker #port').val()) != '0') {
|
||||||
var options = {},
|
var port = String($('div#port-picker #port').val()),
|
||||||
port = String($('div#port-picker #port').val()),
|
|
||||||
baud;
|
baud;
|
||||||
|
|
||||||
switch (GUI.operating_system) {
|
switch (GUI.operating_system) {
|
||||||
|
@ -332,10 +337,6 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
options.reboot_baud = parseInt($('div#port-picker #baud').val());
|
options.reboot_baud = parseInt($('div#port-picker #baud').val());
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($('input.erase_chip').is(':checked')) {
|
|
||||||
options.erase_chip = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ($('input.flash_manual_baud').is(':checked')) {
|
if ($('input.flash_manual_baud').is(':checked')) {
|
||||||
baud = parseInt($('#flash_manual_baud_rate').val());
|
baud = parseInt($('#flash_manual_baud_rate').val());
|
||||||
}
|
}
|
||||||
|
@ -347,7 +348,7 @@ TABS.firmware_flasher.initialize = function (callback) {
|
||||||
GUI.log('<span style="color: red">Please select valid serial port</span>');
|
GUI.log('<span style="color: red">Please select valid serial port</span>');
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
STM32DFU.connect(usbDevices.STM32DFU, parsed_hex);
|
STM32DFU.connect(usbDevices.STM32DFU, parsed_hex, options);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherFirmwareNotLoaded'));
|
$('span.progressLabel').text(chrome.i18n.getMessage('firmwareFlasherFirmwareNotLoaded'));
|
||||||
|
|
Loading…
Reference in New Issue