cancel
Showing results for 
Search instead for 
Did you mean: 

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

Jsilv.1
Associate II

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]

1 ACCEPTED SOLUTION

Accepted Solutions

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 Venmo Up vote any posts that you find helpful, it shows what's working..

View solution in original post

2 REPLIES 2

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 Venmo Up vote any posts that you find helpful, it shows what's working..
Jsilv.1
Associate II

Problem seems solved.

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

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
Delete_Sectors();