cancel
Showing results for 
Search instead for 
Did you mean: 

Problem writing to STM32H563 internal flash memory

PFlor.2
Senior II

I'm developing a bootloader for a project using the STM32H563VGT6 with 1MB of internal flash memory.  I've developed a bootloader in the past for STM32H743 which works correcty.

In this H5 bootloader I seem to have problems writing to the internal flash memory.  Below is the code I have to write a block of data to flash memory.

uint32_t Flash_Write_Data (uint32_t StartSectorAddress, uint32_t *data, uint16_t numberofwords)
{
  static FLASH_EraseInitTypeDef EraseInitStruct;
  uint32_t SECTORError;
  int sofar=0;
  /* Unlock the Flash to enable the flash control register access *************/
  HAL_FLASH_Unlock();
  /* Erase the user Flash area */
  /* Get the number of sector to erase from 1st sector */
  uint32_t StartSector = GetSector(StartSectorAddress);
  uint32_t EndSectorAddress = StartSectorAddress + numberofwords*4;
  uint32_t EndSector = GetSector(EndSectorAddress);

  /* Fill EraseInit structure*/
  EraseInitStruct.TypeErase     = FLASH_TYPEERASE_SECTORS;
  EraseInitStruct.Sector        = StartSector;

  // The the proper BANK to erase the Sector
  if (StartSectorAddress < 0x08100000)
    EraseInitStruct.Banks     = FLASH_BANK_1;
  else EraseInitStruct.Banks    = FLASH_BANK_2;

  EraseInitStruct.NbSectors     = (EndSector - StartSector) + 1;

  if (HAL_FLASHEx_Erase(&EraseInitStruct, &SECTORError) != HAL_OK)
  {
    return HAL_FLASH_GetError ();
  }
  /* Program the user Flash area 8 WORDS at a time
   * (area defined by FLASH_USER_START_ADDR and FLASH_USER_END_ADDR) ***********/
   while (sofar<numberofwords)
   {
     if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD_EDATA, StartSectorAddress, (uint32_t ) &data[sofar]) == HAL_OK)
     {
       StartSectorAddress += 4*8;  //
       sofar+=8;
     }
     else
     {
       /* Error occurred while writing data in Flash memory*/
       return HAL_FLASH_GetError ();
     }
   }
  /* Lock the Flash to disable the flash control register access (recommended
     to protect the FLASH memory against possible unwanted operation) *********/
  HAL_FLASH_Lock();

  return 0;
}

I'm calling this to write a block of 4096 bytes of data to flash address 0x08020000.  The HAL_FLASHEx_Erase() seems to execute ok and returns HAL_OK status, but when I view the area of memory that should be erased the old data still exists.  The variable SECTORError is still at 0xFFFFFFFF when coming out of the flash erase function. Then, once I get down to write the data to flash with HAL_FLASH_Program(), the function returns a status with HAL_TIMEOUT.

One major difference I saw between the STM32H7 and H5 is the mapping of memory sectors so maybe I have this setup wrong.  The STM32H743 I was using in my last project only had 8 sectors per flash memory bank (2 banks for 2MB flash memory) with 128KB per sector.  Based on what I've been able to get from the STM32H563 datasheet, the H5 has 32 sectors for each bank (only 1 bank of 1MB for the H5 I am using) with 32KB per sector.  So with the code above, the GetSector function returns sector 4 that is used in the EraseInitStruct in which Sector is set to 4 and NbSectors is set to 1.  Below shows how I have the memory sectors setup...any advice would be appreciated.

static uint32_t GetSector(uint32_t Address)
{
  uint32_t sector = 0;

  /* BANK 1 */
  if((Address >= 0x08000000) && (Address < 0x08008000)) { sector = FLASH_SECTOR_0;}

  else if((Address >= 0x08008000) && (Address < 0x08010000)) { sector = FLASH_SECTOR_1;}

  else if((Address >= 0x08010000) && (Address < 0x08018000)) { sector = FLASH_SECTOR_2;}

  else if((Address >= 0x08018000) && (Address < 0x08020000)) { sector = FLASH_SECTOR_3;}

  else if((Address >= 0x08020000) && (Address < 0x08028000)) { sector = FLASH_SECTOR_4;}

  else if((Address >= 0x08028000) && (Address < 0x08030000)) { sector = FLASH_SECTOR_5;}

  else if((Address >= 0x08030000) && (Address < 0x08038000)) { sector = FLASH_SECTOR_6;}

  else if((Address >= 0x08038000) && (Address < 0x08040000)) { sector = FLASH_SECTOR_7;}

  else if((Address >= 0x08040000) && (Address < 0x08048000)) { sector = FLASH_SECTOR_8;}

  else if((Address >= 0x08048000) && (Address < 0x08050000)) { sector = FLASH_SECTOR_9;}

  else if((Address >= 0x08050000) && (Address < 0x08058000)) { sector = FLASH_SECTOR_10;}

  else if((Address >= 0x08058000) && (Address < 0x08060000)) { sector = FLASH_SECTOR_11;}

  else if((Address >= 0x08060000) && (Address < 0x08068000)) { sector = FLASH_SECTOR_12;}

  else if((Address >= 0x08068000) && (Address < 0x08070000)) { sector = FLASH_SECTOR_13;}

  else if((Address >= 0x08070000) && (Address < 0x08078000)) { sector = FLASH_SECTOR_14;}

  else if((Address >= 0x08078000) && (Address < 0x08080000)) { sector = FLASH_SECTOR_15;}

  else if((Address >= 0x08080000) && (Address < 0x08088000)) { sector = FLASH_SECTOR_16;}

  else if((Address >= 0x08088000) && (Address < 0x08090000)) { sector = FLASH_SECTOR_17;}

  else if((Address >= 0x08090000) && (Address < 0x08098000)) { sector = FLASH_SECTOR_18;}

  else if((Address >= 0x08098000) && (Address < 0x080A0000)) { sector = FLASH_SECTOR_19;}

  else if((Address >= 0x080A0000) && (Address < 0x080A8000)) { sector = FLASH_SECTOR_20;}

  else if((Address >= 0x080A8000) && (Address < 0x080B0000)) { sector = FLASH_SECTOR_21;}

  else if((Address >= 0x080B0000) && (Address < 0x080B8000)) { sector = FLASH_SECTOR_22;}

  else if((Address >= 0x080B8000) && (Address < 0x080C0000)) { sector = FLASH_SECTOR_23;}

  else if((Address >= 0x080C0000) && (Address < 0x080C8000)) { sector = FLASH_SECTOR_24;}

  else if((Address >= 0x080C8000) && (Address < 0x080D0000)) { sector = FLASH_SECTOR_25;}

  else if((Address >= 0x080D0000) && (Address < 0x080D8000)) { sector = FLASH_SECTOR_26;}

  else if((Address >= 0x080D8000) && (Address < 0x080E0000)) { sector = FLASH_SECTOR_27;}

  else if((Address >= 0x080E0000) && (Address < 0x080E8000)) { sector = FLASH_SECTOR_28;}

  else if((Address >= 0x080E8000) && (Address < 0x080F0000)) { sector = FLASH_SECTOR_29;}

  else if((Address >= 0x080F0000) && (Address < 0x080F8000)) { sector = FLASH_SECTOR_30;}

  else if((Address >= 0x080F8000) && (Address < 0x08100000)) { sector = FLASH_SECTOR_31;}

   

0 REPLIES 0