cancel
Showing results for 
Search instead for 
Did you mean: 

Flash read / write issue on H5 (H573) => Runs onto NMI when reading the FLASH

Alban
Associate II

Hello,


I'm working on a software port from a STM32F413 to a STM32H573. I'm done with the application but I'm facing issues with the bootloader.
On H5 it looks like it's possible to write flash only with 128 bits sections. On F4 it was possible with 8 bits and 32 bits.
In order to handle the legacy code, I've writen this function that reads the 128 bits, replaces a part by my 8 new bits and then writes it back.

Here the code:

 

 

 

static bool _BOARD_writeFlash(WORD_SIZE wordSize, uint32_t* writeData, uint32_t writeAdr)
{
  bool ret = true;

 if (HAL_OK == HAL_FLASH_Unlock())
  {
    if (WORD_SIZE_8 == wordSize) // uint8
    {
      uint32_t quadWord[4];               // Array to hold 16 bytes (128 bits)
      uint32_t alignedAddress = writeAdr & ~0xF; // Align address to 16-byte boundary

      while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY)) {
          // Wait for the flash controller to be ready
      }
      __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS);
      
      // Read the current quadword from flash (16 bytes)
      for (int i = 0; i < 4; i++) {
        quadWord[i] = *((volatile uint32_t*)(alignedAddress + (i * sizeof(uint32_t))));
      }

      uint32_t offset = writeAdr % 16; // Offset within the 16-byte quadword
      uint32_t wordIndex = offset / 4; // Identify the 32-bit word containing the byte
      uint32_t byteShift = (offset % 4) * 8; // Calculate shift for the byte in the word

      quadWord[wordIndex] &= ~(0xFF << byteShift); // Clear the target byte
      quadWord[wordIndex] |= ((*writeData & 0xFF) << byteShift); // Set the new byte value

      ret = ret && (HAL_OK == HAL_FLASH_Program(FLASH_TYPEPROGRAM_QUADWORD, alignedAddress, (uint32_t)quadWord));
    }
    HAL_FLASH_Lock();
  }
  else
  {
    FLASH_FUNC_LOGE("Can't unlock flash");
    ret = false;
  }

  return ret;
}

 

 

Sorry for the bad quality code, I'm just trying to make this work. I'll clean right after.
This function also handles 16 bits word size write in the same way and it works perfectly fine (No NMI).


I run onto a NMI right after the first call to "quadWord[i] = *((volatile uint32_t*)(alignedAddress + (i * sizeof(uint32_t))));"

The problematic instruction is "add r2, sp, #24":

Alban_0-1733218294022.png

Does anyone already faces this issue while porting code from F4 to H5? Any clue or workaround?
I'll appreciate!

1 ACCEPTED SOLUTION

Accepted Solutions

FYI I fixed my problem. As I said previously, I work on a software portage from F4 to H5 and I missed a compilation flag change. I left a ```-mcpu=cortex-m4``` instead of ```-mcpu=cortex-m33``` and the consequence was that the instruction set was ARM7 and not ARM8. With the correct flag, the read/write works fine. 
Thanks for your time!

View solution in original post

9 REPLIES 9

@Alban wrote:

On H5 it looks like it's possible to write flash only with 128 bits sections. iate!


Indeed - except the OTP and high-cycle data area:

AndrewNeil_0-1733219097668.png

https://www.st.com/resource/en/reference_manual/rm0481-stm32h52333xx-stm32h56263xx-and-stm32h573xx-armbased-32bit-mcus-stmicroelectronics.pdf#page=245

 

 

That's true!
But I'm writting between 0x8000000 and 0x80F0000. And for what I've seen, OTP memory is somewhere at 0x08FFF800 (Or even further). 
Sorry for the shortcut!

Sarra.S
ST Employee

Hello @Albancould you verify that the memory region you are accessing is not protected? 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

I have to say I can't find a way to check this on STM32H573. 
All informations I found talks about RDP and it looks like it's not part of the H5 anymore.
What would be the solution to check read protection status on H573?

Hello again, 

>>All informations I found talks about RDP and it looks like it's not part of the H5 anymore. 

The RDP mechanism has been replaced by a new scheme called PRODUCT_STATE, you can check What is replaced o the stm32H5 MCUs.

 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Hello Sarra,

 

PRODUCT_STATE is on STATE_OPEN right before I read. So I guess my memory isn't protected.

Hello again, rethinking of the issue, I believe you have a double ECC error, causing an NMI. 

Referring to the RM, when two ECC errors occur during a read, the flash interface sets the double error detection flag ECCD in the FLASH_ECCDETR register, and when this flag is raised, an NMI is generated!

Could you quickly check if the ECCD flag is raised in FLASH_ECCDETR register?  

If this is the case, you must invalidate the instruction cache (CACHEINV = 1) in the NMI interrupt service routine and it'll be resolved. 

To give better visibility on the answered topics, please click on Accept as Solution on the reply which solved your issue or answered your question.

Thanks for the answer.
The ECCD flag of the FLASH_ECCDETR register is indeed raised. ICACHE isn't enable yet on my project.

Could you please explain why a simple read creates a double ECC error? 

FYI I fixed my problem. As I said previously, I work on a software portage from F4 to H5 and I missed a compilation flag change. I left a ```-mcpu=cortex-m4``` instead of ```-mcpu=cortex-m33``` and the consequence was that the instruction set was ARM7 and not ARM8. With the correct flag, the read/write works fine. 
Thanks for your time!