2019-08-27 07:04 PM
I have an stm32h745zit6 on my own board, where I can write correctly to the CM7 section (0x0800 0000 to 0x080F FFFF range) but not to the CM4 section (0x0810 0000 to 0x081E FFFF range), I also can't do a full erase of the chip, and it will give me an "Error: Mass erase operation failed.Please verify flash protection" error.
What my suspicion is that the option bytes at some point got messed up, but when reading the option bytes from memory the values don't make a lot of sense, and there are more bytes than what in the reference manual is indicated. (I attached the option bytes as a reference.)
To my knowledge I didn't write these option bytes, and don't have another one available now to test on as well, anything that I can do? As indicated, I do have access to the CM7 core, so I could write the default values to the option bytes, but would rather confirm here before messing stuff up and would need to know how to do this correctly.
Best, Hans
2019-08-27 07:37 PM
Which tools do you use?
2019-08-27 07:56 PM
I used
reading the RDPLevel it is set to OB_RDP_LEVEL_0, reading WRPState for FLASH_BANK_2 returns OB_WRPSTATE_DISABLE
2019-08-27 08:12 PM
I don't know DFU. Have you got a debug port and a reset button on your board? If yes get System Workbench (supports dual core) and try it with a small test application first. I have got the STM32H745I-Disco board and I can program both sections and start both cores in a controlled manner.
2019-08-28 07:01 PM
I don't have the debug port on it, we did some testing with this code:
HAL_FLASH_Unlock(); //unlock flash writing
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS_BANK1 | FLASH_FLAG_ALL_ERRORS_BANK2);
FLASH_EraseInitTypeDef EraseInitStruct;
EraseInitStruct.Banks = FLASH_BANK_2;
EraseInitStruct.Sector = FLASH_SECTOR_0;
EraseInitStruct.TypeErase = TYPEERASE_SECTORS;
EraseInitStruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
EraseInitStruct.NbSectors = 1;
uint32_t SectorError = 0;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &SectorError) == HAL_OK)
{
uint32_t saveData[8] = {0x12345678, 0x12345678,0x12345678,0x12345678,0x12345678,0x12345678,0x12345678,0x12345678};
HAL_FLASH_Program(FLASH_TYPEPROGRAM_FLASHWORD,FLASH_BANK2_BASE,(uint32_t)saveData);
}
HAL_FLASH_Lock();
and this works, we can read the code fine with stm32cubeprogrammer, but writing it isn't possible. Might be a DFU protocol issue?
We are suspicious that the DFU flashers aren't selecting Bank 2 and are just using Bank 1.
2019-08-28 09:27 PM
In the \DFU_Standalone example, it actually is hardcoded to BANK_1
uint16_t Flash_If_Erase(uint32_t Add)
{
uint32_t startsector = 0, sectorerror = 0;
/* Variable contains Flash operation status */
HAL_StatusTypeDef status;
FLASH_EraseInitTypeDef eraseinitstruct;
/* Get the number of sector */
startsector = GetSector(Add);
eraseinitstruct.TypeErase = FLASH_TYPEERASE_SECTORS;
eraseinitstruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
eraseinitstruct.Banks = FLASH_BANK_1;
eraseinitstruct.Sector = startsector;
eraseinitstruct.NbSectors = 1;
status = HAL_FLASHEx_Erase(&eraseinitstruct, §orerror);
if (status != HAL_OK)
{
return 1;
}
return 0;
}
if this is actually used in the bootloader, it will never work. GetSector uses it correctly.
the code should be something like
uint16_t Flash_If_Erase(uint32_t Add)
{
uint32_t startsector = 0, sectorerror = 0;
/* Variable contains Flash operation status */
HAL_StatusTypeDef status;
FLASH_EraseInitTypeDef eraseinitstruct;
/* Get the number of sector */
startsector = GetSector(Add);
eraseinitstruct.TypeErase = FLASH_TYPEERASE_SECTORS;
eraseinitstruct.VoltageRange = FLASH_VOLTAGE_RANGE_3;
eraseinitstruct.Banks = ((Add >= 0x08000000) && (Add < 0x08100000)) ? FLASH_BANK_1 : FLASH_BANK_2;
eraseinitstruct.Sector = startsector;
eraseinitstruct.NbSectors = 1;
status = HAL_FLASHEx_Erase(&eraseinitstruct, §orerror);
if (status != HAL_OK)
{
return 1;
}
return 0;
}