mirror of
https://github.com/betaflight/betaflight-configurator.git
synced 2025-07-15 20:35:23 +03:00
Workaround for H7 Rev.V weirdness on erase beyond 1MB
H743 Rev.V (probably other H7 Rev.Vs also) remains in dfuDNBUSY state after the specified delay time. STM32CubeProgrammer deals with behavior with an undocumented procedure as follows. 1. Issue DFU_CLRSTATUS, which ends up with (14,10) = (errUNKNOWN, dfuERROR) 2. Issue another DFU_CLRSTATUS which delivers (0,2) = (OK, dfuIDLE) 3. Treat the current erase successfully finished. Here in this PR, we call clarStatus to get to the dfuIDLE state when dfuDNBUSY is detected after timeout. --- Below is the complete description of the problem reported at ST community (https://community.st.com/s/question/0D50X0000C0w7U9SQI/weird-stm32h743zi-revv-usb-dfu-erase-behavior-beyond-1mb-page-8) Weird STM32H743ZI Rev.V USB DFU erase behavior beyond 1MB (sector 8) Summary I'm observing errors and what looks like a non-standard error recovery procedure for all sectors beyond 1MB (sectors 8 through 15) during sector erase on STM32H743ZI Rev.V (Nucleo-H743ZI2) under STM32CubeProgrammer. Is this behavior documented anywhere? Description For sector erase start to sector 2 erase, a log from the STM32CubeProgrammer looks like this. 13:05:04:121 : Flash sector erase ... 13:05:04:121 : DFU status = 0 13:05:04:121 : DFU State = 9 13:05:04:121 : Status: 0, State: 9 13:05:04:121 : sending an abort request 13:05:04:122 : DFU status = 0 13:05:04:122 : DFU State = 2 13:05:04:122 : sending a page erase request @: 0x08000000 13:05:04:122 : data: 4100000008 13:05:05:025 : DFU status = 0 13:05:05:025 : DFU State = 4 13:05:05:026 : DFU status = 0 13:05:05:027 : DFU State = 5 13:05:05:027 : erasing sector 0000 @: 0x08000000 done 13:05:05:027 : DFU status = 0 13:05:05:027 : DFU State = 5 13:05:05:027 : Status: 0, State: 5 13:05:05:027 : sending a page erase request @: 0x08020000 13:05:05:027 : data: 4100000208 13:05:05:932 : DFU status = 0 13:05:05:932 : DFU State = 4 13:05:05:933 : DFU status = 0 13:05:05:934 : DFU State = 5 13:05:05:934 : erasing sector 0001 @: 0x08020000 done 13:05:05:935 : DFU status = 0 13:05:05:936 : DFU State = 5 13:05:05:936 : Status: 0, State: 5 ... I notice that sector erase requests are followed by what seems like a pair of GETSTATUS results, with (status, state) being (0, 4) and (0,5) and then declared as erase done. States 4 and 5 are probably dfuDNBUSY and dfuDNLOAD-IDLE respectively. All sectors within the first 1MB (sectors 0 through 7) behaves the same. But for sectors beyond 1MB, it looks like this. 13:05:11:397 : DFU status = 0 13:05:11:397 : DFU State = 5 13:05:11:397 : Status: 0, State: 5 13:05:11:397 : sending a page erase request @: 0x08100000 13:05:11:397 : data: 4100001008 13:05:11:413 : DFU status = 0 13:05:11:413 : DFU State = 4 13:05:11:414 : DFU status = 0 13:05:11:414 : DFU State = 4 13:05:13:419 : sending a clear status request 13:05:13:421 : DFU status = 14 13:05:13:421 : DFU State = 10 13:05:13:421 : an error occured after sending the clear status request 13:05:13:421 : Status: errUNKNOWN, State: dfuERROR 13:05:13:421 : DFU status = 14 13:05:13:422 : DFU State = 10 13:05:13:422 : sending a clear status request 13:05:13:422 : DFU status = 0 13:05:13:422 : DFU State = 2 13:05:13:422 : DFU status = 0 13:05:13:422 : DFU State = 2 13:05:13:422 : erasing sector 0008 @: 0x08100000 done Notice that GETSTATUS results are now (0,4) and (0,4), followed by CLEARSTATUS returning (14,10) which is attributed as dfuERROR, and then another CLEARSTATUS (may be two?) that returned (0,2). This particular sector erase process is treated as successful, but it looks like that the process has never confirmed the successful completion of the erase operation but forced clear an error caused by the preceding clear. (status, state) in the process are probably: (14, 10) = (errUNKNOWN, dfuERROR) (0, 2) = (OK, dfuIDLE) Btw, sector erase succeeds with (0,4) (0,5) on STM32H743ZI Rev.Y (Nucleo-H743ZI) for all sectors 0 through 15 under STM32CubeProgrammer.
This commit is contained in:
parent
ed8d2a79a9
commit
8ac29e0563
1 changed files with 38 additions and 11 deletions
|
@ -810,6 +810,19 @@ STM32DFU_protocol.prototype.upload_procedure = function (step) {
|
|||
var page = 0;
|
||||
var total_erased = 0; // bytes
|
||||
|
||||
var erase_page_next = function() {
|
||||
TABS.firmware_flasher.flashProgress((page + 1) / erase_pages.length * 100);
|
||||
page++;
|
||||
|
||||
if(page == erase_pages.length) {
|
||||
console.log("Erase: complete");
|
||||
GUI.log(i18n.getMessage('dfu_erased_kilobytes', (total_erased / 1024).toString()));
|
||||
self.upload_procedure(4);
|
||||
} else {
|
||||
erase_page();
|
||||
}
|
||||
}
|
||||
|
||||
var erase_page = function() {
|
||||
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;
|
||||
|
@ -825,18 +838,32 @@ 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) {
|
||||
// update progress bar
|
||||
TABS.firmware_flasher.flashProgress((page + 1) / erase_pages.length * 100);
|
||||
page++;
|
||||
|
||||
if(page == erase_pages.length) {
|
||||
console.log("Erase: complete");
|
||||
GUI.log(i18n.getMessage('dfu_erased_kilobytes', (total_erased / 1024).toString()));
|
||||
self.upload_procedure(4);
|
||||
}
|
||||
else
|
||||
erase_page();
|
||||
if (data[4] == self.state.dfuDNBUSY) {
|
||||
|
||||
//
|
||||
// H743 Rev.V (probably other H7 Rev.Vs also) remains in dfuDNBUSY state after the specified delay time.
|
||||
// STM32CubeProgrammer deals with behavior with an undocumented procedure as follows.
|
||||
// 1. Issue DFU_CLRSTATUS, which ends up with (14,10) = (errUNKNOWN, dfuERROR)
|
||||
// 2. Issue another DFU_CLRSTATUS which delivers (0,2) = (OK, dfuIDLE)
|
||||
// 3. Treat the current erase successfully finished.
|
||||
// Here, we call clarStatus to get to the dfuIDLE state.
|
||||
//
|
||||
|
||||
console.log('erase_page: dfuDNBUSY after timeout, clearing');
|
||||
|
||||
self.clearStatus(function() {
|
||||
self.controlTransfer('in', self.request.GETSTATUS, 0, 0, 6, 0, function (data) {
|
||||
if (data[4] == self.state.dfuIDLE) {
|
||||
erase_page_next();
|
||||
} else {
|
||||
console.log('Failed to erase page 0x' + page_addr.toString(16) + ' (did not reach dfuIDLE after clearing');
|
||||
self.upload_procedure(99);
|
||||
}
|
||||
})
|
||||
});
|
||||
} else if (data[4] == self.state.dfuDNLOAD_IDLE) {
|
||||
erase_page_next();
|
||||
} else {
|
||||
console.log('Failed to erase page 0x' + page_addr.toString(16));
|
||||
self.upload_procedure(99);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue