Skip to main content
Jsilv.1
Associate II
November 22, 2020
Solved

Hi, I'm developing a bootlader just to download a .bin file and then write starting at 0x8007000 address. My code is based on https://github.com/STMicroelectronics/STM32CubeWB/tree/v1.4.0/Projects/P-NUCLEO-WB55.Nucleo/Applications/BLE/BLE_Ota

  • November 22, 2020
  • 2 replies
  • 1173 views

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]

This topic has been closed for replies.
Best answer by Tesla DeLorean

Have to watch alignment.

Have one chance to program, so retrying isn't going to help, and the memory cell needs to be blank

2 replies

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
November 22, 2020

Have to watch alignment.

Have one chance to program, so retrying isn't going to help, and the memory cell needs to be blank

Tips, Buy me a coffee, or three.. PayPal VenmoUp vote any posts that you find helpful, it shows what's working..
Jsilv.1
Jsilv.1Author
Associate II
November 22, 2020

Problem seems solved.

Before calling Delete_Sectors() it is needed to clear some flags.

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
Delete_Sectors();