diff --git a/js/stm32dfu.js b/js/stm32dfu.js
index 21ded1d54f..3286d69af9 100644
--- a/js/stm32dfu.js
+++ b/js/stm32dfu.js
@@ -59,6 +59,15 @@ STM32DFU_protocol.prototype.connect = function(hex) {
var self = this;
self.hex = hex;
+ // reset and set some variables before we start
+ self.upload_time_start = microtime();
+ self.verify_hex = [];
+
+ // reset progress bar to initial state
+ self.progress_bar_e = $('.progress');
+ self.progress_bar_e.val(0);
+ self.progress_bar_e.removeClass('valid invalid');
+
chrome.usb.getDevices(usbDevices.STM32DFU, function(result) {
if (result.length) {
console.log('USB DFU detected with ID: ' + result[0].device);
@@ -187,7 +196,10 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) {
});
break;
case 3:
- // full erase
+ // full chip erase
+ console.log('Executing global chip erase');
+ STM32.GUI_status('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
@@ -196,7 +208,6 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) {
setTimeout(function() {
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) {
if (data[4] == self.state.dfuDNLOAD_IDLE) {
- console.log('Full Chip Erase Executed');
self.upload_procedure(4);
} else {
// throw some error
@@ -210,12 +221,205 @@ STM32DFU_protocol.prototype.upload_procedure = function(step) {
});
break;
case 4:
- self.upload_procedure(99);
+ // upload
+ console.log('Writing data ...');
+ STM32.GUI_status('Flashing ...');
+
+ var blocks = self.hex.data.length - 1;
+ var flashing_block = 0;
+ var address = self.hex.data[flashing_block].address;
+
+ var bytes_flashed = 0;
+ var bytes_flashed_total = 0; // used for progress bar
+ var wBlockNum = 2; // required by DFU
+
+ // this is unoptimized version of write, where address is set before every transmission, this should be reworked to only transmit addres at the beginning and at block change
+ // such approach should give a nice speed boost (if needed)
+ function write() {
+ 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);
+
+ self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x21, address, (address >> 8), (address >> 16), (address >> 24)], 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) {
+ // address loaded in this stage
+ var data = [];
+ for (var i = 0; i < bytes_to_write; i++) {
+ data.push(self.hex.data[flashing_block].data[bytes_flashed++]);
+ }
+
+ address += bytes_to_write;
+ bytes_flashed_total += bytes_to_write;
+
+ self.controlTransfer('out', self.request.DNLOAD, 2, 0, 0, data, function() {
+ self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function(data) {
+ 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(bytes_flashed_total / (self.hex.bytes_total * 2) * 100);
+
+ // flash another page
+ write();
+ } else {
+ // throw some error
+ console.log(data);
+ }
+ });
+ }, delay);
+ });
+ })
+ } else {
+ // throw some error
+ console.log(data);
+ }
+ });
+ }, delay);
+ } else {
+ // throw some error
+ console.log(data);
+ }
+ });
+ });
+ } else {
+ // move to another block
+ if (flashing_block < blocks) {
+ flashing_block++;
+
+ address = self.hex.data[flashing_block].address;
+ bytes_flashed = 0;
+
+ write();
+ } else {
+ // all blocks flashed
+ console.log('Writing: done');
+
+ // proceed to next step
+ self.upload_procedure(5);
+ }
+ }
+ }
+
+ // start writing
+ write();
break;
case 5:
+ // verify
+ console.log('Verifying data ...');
+ STM32.GUI_status('Verifying ...');
+
+ var blocks = self.hex.data.length - 1;
+ var reading_block = 0;
+ var address = self.hex.data[reading_block].address;
+
+ var bytes_verified = 0;
+ var bytes_verified_total = 0; // used for progress bar
+
+ // initialize arrays
+ for (var i = 0; i <= blocks; i++) {
+ self.verify_hex.push([]);
+ }
+
+ function read() {
+ if (bytes_verified < self.hex.data[reading_block].bytes) {
+ var bytes_to_read = ((bytes_verified + 2048) <= self.hex.data[reading_block].bytes) ? 2048 : (self.hex.data[reading_block].bytes - bytes_verified);
+
+ self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, [0x21, address, (address >> 8), (address >> 16), (address >> 24)], 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) {
+ // address loaded in this stage
+ self.controlTransfer('in', self.request.UPLOAD, 2, 0, bytes_to_read, 0, function(data) { // getting error code 4 so this is obviously wrong, but whats the right approach?
+ console.log(data);
+ for (var i = 0; i < data.length; i++) {
+ self.verify_hex[reading_block].push(data[i]);
+ }
+
+ address += bytes_to_read;
+ bytes_verified += bytes_to_read;
+ bytes_verified_total += bytes_to_read;
+
+ // update progress bar
+ self.progress_bar_e.val((self.hex.bytes_total + bytes_verified_total) / (self.hex.bytes_total * 2) * 100);
+
+ // verify another page
+ read();
+ });
+ } else {
+ // throw some error
+ console.log(data);
+ }
+ });
+ }, delay);
+ } else {
+ // throw some error
+ console.log(data);
+ }
+ });
+ });
+ } else {
+ // move to another block
+ if (reading_block < blocks) {
+ reading_block++;
+
+ address = self.hex.data[reading_block].address;
+ bytes_verified = 0;
+
+ read();
+ } else {
+ // all blocks read, verify
+
+ var verify = true;
+ for (var i = 0; i <= blocks; i++) {
+ verify = self.verify_flash(self.hex.data[i].data, self.verify_hex[i]);
+
+ if (!verify) break;
+ }
+
+ if (verify) {
+ console.log('Programming: SUCCESSFUL');
+ STM32.GUI_status('Programming: SUCCESSFUL');
+
+ // update progress bar
+ self.progress_bar_e.addClass('valid');
+
+ // proceed to next step
+ self.upload_procedure(6);
+ } else {
+ console.log('Programming: FAILED');
+ STM32.GUI_status('Programming: FAILED');
+
+ // update progress bar
+ self.progress_bar_e.addClass('invalid');
+
+ // disconnect
+ self.upload_procedure(99);
+ }
+ }
+ }
+ }
+
+ // start reading
+ read();
+ break;
+ case 6:
+ self.upload_procedure(99);
break;
case 99:
// cleanup
+ console.log('Script finished after: ' + (microtime() - self.upload_time_start).toFixed(4) + ' seconds');
+
self.releaseInterface(0);
break;
}