1
0
Fork 0
mirror of https://github.com/iNavFlight/inav-configurator.git synced 2025-07-16 04:45:18 +03:00
This commit is contained in:
skaman82 2015-11-02 22:07:37 +01:00
parent 278e25a872
commit 06f643812d
30 changed files with 1280 additions and 1143 deletions

View file

@ -61,13 +61,26 @@ var STM32DFU_protocol = function () {
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.
};
// 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;
self.hex = hex;
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
self.upload_time_start = new Date().getTime();
self.verify_hex = [];
@ -89,12 +102,35 @@ STM32DFU_protocol.prototype.connect = function (device, hex, callback) {
});
};
STM32DFU_protocol.prototype.checkChromeError = function() {
if (chrome.runtime.lastError) {
if(chrome.runtime.lastError.message)
console.log(chrome.runtime.lastError.message);
else
console.log(chrome.runtime.lastError);
return true;
}
return false;
}
STM32DFU_protocol.prototype.openDevice = function (device) {
var self = this;
chrome.usb.openDevice(device, function (handle) {
if(self.checkChromeError()) {
console.log('Failed to open USB device!');
GUI.log(chrome.i18n.getMessage('usbDeviceOpenFail'));
if(GUI.operating_system === 'Linux') {
GUI.log(chrome.i18n.getMessage('usbDeviceUdevNotice'));
}
return;
}
self.handle = handle;
GUI.log(chrome.i18n.getMessage('usbDeviceOpened', handle.handle.toString()));
console.log('Device opened with Handle ID: ' + handle.handle);
self.claimInterface(0);
});
@ -104,6 +140,12 @@ STM32DFU_protocol.prototype.closeDevice = function () {
var self = this;
chrome.usb.closeDevice(this.handle, function closed() {
if(self.checkChromeError()) {
console.log('Failed to close USB device!');
GUI.log(chrome.i18n.getMessage('usbDeviceCloseFail'));
}
GUI.log(chrome.i18n.getMessage('usbDeviceClosed'));
console.log('Device closed with Handle ID: ' + self.handle.handle);
self.handle = null;
@ -139,6 +181,8 @@ STM32DFU_protocol.prototype.resetDevice = function (callback) {
};
STM32DFU_protocol.prototype.controlTransfer = function (direction, request, value, _interface, length, data, callback) {
var self = this;
if (direction == 'in') {
// data is ignored
chrome.usb.controlTransfer(this.handle, {
@ -150,6 +194,9 @@ STM32DFU_protocol.prototype.controlTransfer = function (direction, request, valu
'index': _interface,
'length': length
}, function (result) {
if(self.checkChromeError()) {
console.log('USB transfer failed!');
}
if (result.resultCode) console.log(result.resultCode);
var buf = new Uint8Array(result.data);
@ -174,6 +221,9 @@ STM32DFU_protocol.prototype.controlTransfer = function (direction, request, valu
'index': _interface,
'data': arrayBuf
}, function (result) {
if(self.checkChromeError()) {
console.log('USB transfer failed!');
}
if (result.resultCode) console.log(result.resultCode);
callback(result);
@ -217,7 +267,7 @@ STM32DFU_protocol.prototype.loadAddress = function (address, callback) {
if (data[4] == self.state.dfuDNLOAD_IDLE) {
callback(data);
} else {
console.log('Failed to execure address load');
console.log('Failed to execute address load');
self.upload_procedure(99);
}
});
@ -256,32 +306,86 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
});
break;
case 2:
// full chip erase
console.log('Executing global chip erase');
$('span.progressLabel').text('Erasing ...');
// erase
if (self.options.erase_chip) {
// 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('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);
self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x41], 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) {
self.upload_procedure(4);
} else {
console.log('Failed to execute global chip erase');
self.upload_procedure(99);
}
});
}, delay);
} else {
console.log('Failed to initiate global chip erase');
self.upload_procedure(99);
}
setTimeout(function () {
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
if (data[4] == self.state.dfuDNLOAD_IDLE) {
self.upload_procedure(4);
} else {
console.log('Failed to execute global chip erase');
self.upload_procedure(99);
}
});
}, delay);
} else {
console.log('Failed to initiate global chip erase');
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");
GUI.log(chrome.i18n.getMessage('dfu_erased_kilobytes', (erase_pages_n * self.page_size / 1024).toString()));
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;
case 4:
// upload
// we dont need to clear the state as we are already using DFU_DNLOAD
@ -296,9 +400,6 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
var bytes_flashed_total = 0; // used for progress bar
var wBlockNum = 2; // required by DFU
// start
self.loadAddress(address, write);
var write = function () {
if (bytes_flashed < self.hex.data[flashing_block].bytes) {
var bytes_to_write = ((bytes_flashed + 2048) <= self.hex.data[flashing_block].bytes) ? 2048 : (self.hex.data[flashing_block].bytes - bytes_flashed);
@ -353,6 +454,10 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
}
}
}
// start
self.loadAddress(address, write);
break;
case 5:
// verify
@ -463,13 +568,13 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
});
}
// start
clear_before_leave();
break;
case 99:
// cleanup
self.releaseInterface(0);
GUI.connect_lock = false;
var timeSpent = new Date().getTime() - self.upload_time_start;
console.log('Script finished after: ' + (timeSpent / 1000) + ' seconds');