STM32H755 failing to erase bank 1 while running from bank 2 (opposite works fine)
I believe I am seeing the same issue raised here:
but there were no replies before that thread was locked.
I'm working on a firmware-update mechanism, testing on a Nucleo STM32H755ZI (rev U). When a new firmware is available, I erase the inactive flash bank and then write the new firmware into the freshly erased bank, ping-ponging between banks each time the firmware gets updated.
// Find which flash bank we are running in now
if (FLASH->OPTCR & FLASH_OPTCR_SWAP_BANK)
{
ActiveBank = BANK2;
}
else
{
ActiveBank = BANK1;
}
...
// Bank-erase the inactive flash, and prepare to program it
if (ActiveBank == BANK1)
{
// Only unlock if currently locked
if (FLASH->CR2 & FLASH_CR_LOCK)
{
FLASH->KEYR2 = 0x45670123;
FLASH->KEYR2 = 0xcdef89ab;
}
FLASH->CR2 |= (FLASH_CR_BER | FLASH_CR_START); // perform bank 2 erase
while (FLASH->SR2 & FLASH_SR_QW)
{ }
FLASH->CR2 |= FLASH_CR_PG; // enable programming on this bank
}
else
{
// Only unlock if currently locked
if (FLASH->CR1 & FLASH_CR_LOCK)
{
FLASH->KEYR1 = 0x45670123;
FLASH->KEYR1 = 0xcdef89ab;
}
FLASH->CR1 |= (FLASH_CR_BER | FLASH_CR_START); // perform bank 1 erase
while (FLASH->SR1 & FLASH_SR_QW)
{ }
FLASH->CR1 |= FLASH_CR_PG; // enable programming on this bank
}
// then we program flash words with the incoming data (not shown)After flash programming, I compute a SHA hash of the newly written firmware and compare it to the expected. If that validation check passes, I perform an option-byte update to flip the SWAP_BANK_OPT bit, then reset to boot into the other bank:
// Only unlock if currently locked
if (FLASH->OPTCR & FLASH_OPTCR_OPTLOCK)
{
FLASH->OPTKEYR = 0x08192a3b;
FLASH->OPTKEYR = 0x4c5d6e7f;
}
FLASH->OPTSR_PRG ^= FLASH_OPTSR_SWAP_BANK_OPT; // toggle the SWAP_BANK_OPT bit
FLASH->OPTCR |= FLASH_OPTCR_OPTSTART; // start option-byte write
while (FLASH->OPTSR_CUR & FLASH_OPTSR_OPT_BUSY) // wait for it to complete
{ }
// generate a software reset of the CM7 core
SCB->AIRCR = (0x5fa << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk;All of this works great when the original firmware (flashed with STM32Cube programmer to 0x08000000) is running in bank 1, and I send a new firmware image. The new image gets programmed, verified, and the system resets and is now running in Bank 2.
Unfortunately, if I send another image, which should cause a bank-erase of Bank 1, programming of Bank 1, and reset into Bank 1, the process fails at the bank erase: The write to FLASH_CR1 never returns. Furthermore, the board will not boot again until I re-flash the firmware, which suggests that the "Bank 1" erase is somehow erasing Bank 2, instead of or in addition to, Bank 1.
Any insight as to what may be going wrong here?

