2020-11-22 10:51 AM
I follow the same approach with the magic value 0x94448A29 and so on.
Burning firmware + bootloader works ok, also I can jump to the bootloader using the SRAM1_BASE address to write the reset type.
The problem is that sometimes I got errors writing to the flash.
HAL_FLASH_GetError() returns 0x00000008.
This is the loop that writes the flash.
while (i <= diff2) {
diff = end - from;
////snprintf(buffer, 64, "%d of %d 0x%08x\n", diff, diff2,Address);
////DEBUG(buffer);
while (LL_FLASH_IsActiveFlag_OperationSuspended());
//Create an uint64_t little endian
int k;
uint64_t val = 0;
for (k = 7; k >= 0; --k) {
val <<= 8;
val |= (uint64_t) from[k];
}
uint32_t retries = 3; //in case of error
do
{
uint32_t ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, val);
switch (ret) {
case HAL_OK:
retries = 0;
break;
case HAL_TIMEOUT:
DEBUG("Timeout!\n");
retries--;
break;
case HAL_ERROR:
snprintf(buffer, 64, "Error 0x%08x at 0x%08x\n", HAL_FLASH_GetError(),Address);
DEBUG(buffer);
HAL_FLASH_Lock();
LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0);
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR |
FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR);
while (LL_HSEM_1StepLock(HSEM, CFG_HW_FLASH_SEMID));
HAL_FLASH_Unlock();
while (LL_FLASH_IsActiveFlag_OperationSuspended());
ret = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, val);
retries--;
break;
default:
snprintf(buffer, 64, "HAL_FLASH_Program() unknown status %lu\n",ret);
DEBUG(buffer);
retries--;
}
}while(retries != 0);
from = from + sizeof(uint64_t);
Address += sizeof(uint64_t);
i = i + sizeof(uint64_t);
while (__HAL_FLASH_GET_FLAG(FLASH_FLAG_BSY) != 0) ;
}
HAL_FLASH_Lock();
LL_HSEM_ReleaseLock(HSEM, CFG_HW_FLASH_SEMID, 0);
So HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, Address, val); returns HAL_ERROR and HAL_FLASH_GetError() returns 0x00000008.
I always delete pages from 7 to 25 before starting to write into the flash.
What could be happening? What is this 0x00000008 value?
static void Delete_Sectors( void )
{
/**
* The number of sectors to erase is read from SRAM1.
* It shall be checked whether the number of sectors to erase does not overlap on the secured Flash
* The limit can be read from the SFSA option byte which provides the first secured sector address.
*/
uint32_t page_error;
FLASH_EraseInitTypeDef p_erase_init;
uint32_t first_secure_sector_idx;
first_secure_sector_idx = (READ_BIT(FLASH->SFR, FLASH_SFR_SFSA) >> FLASH_SFR_SFSA_Pos);
p_erase_init.TypeErase = FLASH_TYPEERASE_PAGES;
p_erase_init.Page = CFG_OTA_START_SECTOR_IDX_VAL_MSG;
if(p_erase_init.Page < (CFG_APP_START_SECTOR_INDEX - 1))
{
/**
* Something has been wrong as there is no case we should delete the BLE_Ota application
* Reboot on the firmware application
*/
CFG_OTA_REBOOT_VAL_MSG = CFG_REBOOT_ON_FW_APP;
NVIC_SystemReset(); /* it waits until reset */
}
p_erase_init.NbPages = CFG_OTA_NBR_OF_SECTOR_VAL_MSG;
if ((p_erase_init.Page + p_erase_init.NbPages) > first_secure_sector_idx)
{
p_erase_init.NbPages = first_secure_sector_idx - p_erase_init.Page;
}
//p_erase_init.NbPages = 255;//first_secure_sector_idx - p_erase_init.Page;
snprintf(buffer,64,"Delete page %d to %d\n",p_erase_init.Page,p_erase_init.NbPages);
DEBUG(buffer);
HAL_FLASH_Unlock();
HAL_FLASHEx_Erase(&p_erase_init, &page_error);
HAL_FLASH_Lock();
return;
}
I see no errors when I delete manually the pages using the STM32_Programmer.
STM32_Programmer.sh -c port=swd -e [7 25]
Solved! Go to Solution.
2020-11-22 11:01 AM
Have to watch alignment.
Have one chance to program, so retrying isn't going to help, and the memory cell needs to be blank
2020-11-22 11:01 AM
Have to watch alignment.
Have one chance to program, so retrying isn't going to help, and the memory cell needs to be blank
2020-11-22 11:19 AM
Problem seems solved.
Before calling Delete_Sectors() it is needed to clear some flags.
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
Delete_Sectors();