DFU: Support STM32F4
parent
b46a5e8053
commit
9fbb6337b6
|
@ -213,7 +213,7 @@
|
||||||
"message": "Erased $1 kB of flash <span style=\"color: #57a929\">successfully</span>"
|
"message": "Erased $1 kB of flash <span style=\"color: #57a929\">successfully</span>"
|
||||||
},
|
},
|
||||||
"dfu_device_flash_info": {
|
"dfu_device_flash_info": {
|
||||||
"message": "Detected device with $1*$2 kiB pages, total size $3 kiB"
|
"message": "Detected device with total flash size $1 kiB"
|
||||||
},
|
},
|
||||||
"dfu_error_image_size": {
|
"dfu_error_image_size": {
|
||||||
"message": "<span style=\"color: red; font-weight: bold\">Error</span>: Supplied image is larger then flash available on the chip! Image: $1 kiB, limit = $2 kiB"
|
"message": "<span style=\"color: red; font-weight: bold\">Error</span>: Supplied image is larger then flash available on the chip! Image: $1 kiB, limit = $2 kiB"
|
||||||
|
|
|
@ -62,9 +62,7 @@ var STM32DFU_protocol = function () {
|
||||||
dfuERROR: 10 // An error has occurred. Awaiting the DFU_CLRSTATUS request.
|
dfuERROR: 10 // An error has occurred. Awaiting the DFU_CLRSTATUS request.
|
||||||
};
|
};
|
||||||
|
|
||||||
this.page_size = 0;
|
this.flash_layout = { 'start_address': 0, 'total_size': 0, 'sectors': []};
|
||||||
this.available_flash_size = 0;
|
|
||||||
this.start_address = 0;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
STM32DFU_protocol.prototype.connect = function (device, hex, options, callback) {
|
STM32DFU_protocol.prototype.connect = function (device, hex, options, callback) {
|
||||||
|
@ -257,40 +255,65 @@ STM32DFU_protocol.prototype.getFlashInfo = function (_interface, callback) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//@Internal Flash /0x08000000/128*0002Kg
|
// F303: "@Internal Flash /0x08000000/128*0002Kg"
|
||||||
|
// F407: "@Internal Flash /0x08000000/04*016Kg,01*064Kg,07*128Kg"
|
||||||
|
// split main into [location, start_addr, sectors]
|
||||||
var tmp1 = str.split('/');
|
var tmp1 = str.split('/');
|
||||||
if (tmp1.length != 3) {
|
if (tmp1.length != 3 || !tmp1[0].startsWith("@Internal Flash")) {
|
||||||
callback({}, -1);
|
callback({}, -1);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var tmp2 = tmp1[2].split('*');
|
var type = tmp1[0].trim().replace('@', '');
|
||||||
if (tmp2.length != 2 || tmp2[1].length != 6) {
|
var start_address = parseInt(tmp1[1]);
|
||||||
|
|
||||||
|
// split sectors into array
|
||||||
|
var sectors = [];
|
||||||
|
var total_size = 0;
|
||||||
|
var tmp2 = tmp1[2].split(',');
|
||||||
|
if (tmp2.length < 1) {
|
||||||
callback({}, -2);
|
callback({}, -2);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
for (var i = 0; i < tmp2.length; i++) {
|
||||||
var page_size = parseInt(tmp2[1].substr(0, 4));
|
// split into [num_pages, page_size]
|
||||||
if (!page_size) {
|
var tmp3 = tmp2[i].split('*');
|
||||||
callback({}, -3);
|
if (tmp3.length != 2) {
|
||||||
return;
|
callback({}, -3);
|
||||||
}
|
return;
|
||||||
var unit = tmp2[1].substr(4, 1);
|
}
|
||||||
switch (unit) {
|
var num_pages = parseInt(tmp3[0]);
|
||||||
case 'M':
|
var page_size = parseInt(tmp3[1]);
|
||||||
page_size *= 1024; // fall through to K as well
|
if (!page_size) {
|
||||||
case 'K':
|
|
||||||
page_size *= 1024;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
callback({}, -4);
|
callback({}, -4);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
var unit = tmp3[1].slice(-2, -1);
|
||||||
|
switch (unit) {
|
||||||
|
case 'M':
|
||||||
|
page_size *= 1024; // fall through to K as well
|
||||||
|
case 'K':
|
||||||
|
page_size *= 1024;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
callback({}, -4);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
sectors.push({
|
||||||
|
'num_pages' : num_pages,
|
||||||
|
'start_address': start_address + total_size,
|
||||||
|
'page_size' : page_size,
|
||||||
|
'total_size' : num_pages * page_size
|
||||||
|
});
|
||||||
|
|
||||||
|
total_size += num_pages * page_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
var flash = {
|
var flash = {
|
||||||
'start_address': parseInt(tmp1[1]),
|
'type' : type,
|
||||||
'num_pages' : parseInt(tmp2[0]),
|
'start_address': start_address,
|
||||||
'page_size' : page_size,
|
'sectors' : sectors,
|
||||||
'total_size' : parseInt(tmp2[0]) * page_size
|
'total_size' : total_size
|
||||||
}
|
}
|
||||||
|
|
||||||
callback(flash, resultCode);
|
callback(flash, resultCode);
|
||||||
|
@ -424,12 +447,10 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
||||||
console.log('Failed to detect chip flash info, resultCode: ' + resultCode);
|
console.log('Failed to detect chip flash info, resultCode: ' + resultCode);
|
||||||
self.upload_procedure(99);
|
self.upload_procedure(99);
|
||||||
} else {
|
} else {
|
||||||
self.page_size = flash.page_size;
|
self.flash_layout = flash;
|
||||||
self.start_address = flash.start_address;
|
self.available_flash_size = flash.total_size - (self.hex.start_linear_address - flash.start_address);
|
||||||
self.available_flash_size = flash.total_size - (self.hex.start_linear_address - self.start_address);
|
|
||||||
|
|
||||||
GUI.log(chrome.i18n.getMessage('dfu_device_flash_info', [flash.num_pages.toString(),
|
GUI.log(chrome.i18n.getMessage('dfu_device_flash_info', (flash.total_size / 1024).toString()));
|
||||||
(flash.page_size / 1024).toString(), (flash.total_size / 1024).toString()]));
|
|
||||||
|
|
||||||
if (self.hex.bytes_total > self.available_flash_size) {
|
if (self.hex.bytes_total > self.available_flash_size) {
|
||||||
GUI.log(chrome.i18n.getMessage('dfu_error_image_size',
|
GUI.log(chrome.i18n.getMessage('dfu_error_image_size',
|
||||||
|
@ -475,17 +496,41 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
||||||
} else {
|
} else {
|
||||||
// local erase
|
// local erase
|
||||||
|
|
||||||
var max_address = self.hex.data[self.hex.data.length - 1].address + self.hex.data[self.hex.data.length - 1].bytes - 0x8000000,
|
// find out which pages to erase
|
||||||
erase_pages_n = Math.ceil(max_address / self.page_size),
|
var erase_pages = [];
|
||||||
page = 0;
|
for (var i = 0; i < self.flash_layout.sectors.length; i++) {
|
||||||
|
for (var j = 0; j < self.flash_layout.sectors[i].num_pages; j++) {
|
||||||
|
var page_start = self.flash_layout.sectors[i].start_address + j * self.flash_layout.sectors[i].page_size;
|
||||||
|
var page_end = page_start + self.flash_layout.sectors[i].page_size - 1;
|
||||||
|
for (var k = 0; k < self.hex.data.length; k++) {
|
||||||
|
var starts_in_page = self.hex.data[k].address >= page_start && self.hex.data[k].address <= page_end;
|
||||||
|
var end_address = self.hex.data[k].address + self.hex.data[k].bytes - 1;
|
||||||
|
var ends_in_page = end_address >= page_start && end_address <= page_end;
|
||||||
|
var spans_page = self.hex.data[k].address < page_start && end_address > page_end;
|
||||||
|
if (starts_in_page || ends_in_page || spans_page) {
|
||||||
|
var idx = erase_pages.findIndex(function (element, index, array) {
|
||||||
|
return element.sector == i && element.page == j;
|
||||||
|
});
|
||||||
|
if (idx == -1)
|
||||||
|
erase_pages.push({'sector': i, 'page': j});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
$('span.progressLabel').text('Erasing ...');
|
$('span.progressLabel').text('Erasing ...');
|
||||||
console.log('Executing local chip erase');
|
console.log('Executing local chip erase');
|
||||||
console.log('Erasing. page: 0x00 - 0x' + erase_pages_n.toString(16));
|
|
||||||
|
var page = 0;
|
||||||
|
var total_erased = 0; // bytes
|
||||||
|
|
||||||
var erase_page = function() {
|
var erase_page = function() {
|
||||||
var page_addr = page * self.page_size + self.hex.start_linear_address;
|
var page_addr = erase_pages[page].page * self.flash_layout.sectors[erase_pages[page].sector].page_size +
|
||||||
|
self.flash_layout.sectors[erase_pages[page].sector].start_address;
|
||||||
var cmd = [0x41, page_addr & 0xff, (page_addr >> 8) & 0xff, (page_addr >> 16) & 0xff, (page_addr >> 24) & 0xff];
|
var cmd = [0x41, page_addr & 0xff, (page_addr >> 8) & 0xff, (page_addr >> 16) & 0xff, (page_addr >> 24) & 0xff];
|
||||||
|
total_erased += self.flash_layout.sectors[erase_pages[page].sector].page_size;
|
||||||
|
console.log('Erasing. sector ' + erase_pages[page].sector +
|
||||||
|
', page ' + erase_pages[page].page + ' @ 0x' + page_addr.toString(16));
|
||||||
|
|
||||||
self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, cmd, function () {
|
self.controlTransfer('out', self.request.DNLOAD, 0, 0, 0, cmd, 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) {
|
||||||
|
@ -496,24 +541,24 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
||||||
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) {
|
||||||
// update progress bar
|
// update progress bar
|
||||||
self.progress_bar_e.val((page + 1) / erase_pages_n * 100);
|
self.progress_bar_e.val((page + 1) / erase_pages.length * 100);
|
||||||
page++;
|
page++;
|
||||||
|
|
||||||
if(page == erase_pages_n) {
|
if(page == erase_pages.length) {
|
||||||
console.log("Erase: complete");
|
console.log("Erase: complete");
|
||||||
GUI.log(chrome.i18n.getMessage('dfu_erased_kilobytes', (erase_pages_n * self.page_size / 1024).toString()));
|
GUI.log(chrome.i18n.getMessage('dfu_erased_kilobytes', (total_erased / 1024).toString()));
|
||||||
self.upload_procedure(4);
|
self.upload_procedure(4);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
erase_page();
|
erase_page();
|
||||||
} else {
|
} else {
|
||||||
console.log('Failed to erase page 0x' + self.current_page.toString(16));
|
console.log('Failed to erase page 0x' + page_addr.toString(16));
|
||||||
self.upload_procedure(99);
|
self.upload_procedure(99);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}, delay);
|
}, delay);
|
||||||
} else {
|
} else {
|
||||||
console.log('Failed to initiate page erase, page 0x' + self.current_page.toString(16));
|
console.log('Failed to initiate page erase, page 0x' + page_addr.toString(16));
|
||||||
self.upload_procedure(99);
|
self.upload_procedure(99);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue