Skip to main content
Jsilv.1
Associate II
Nov 22, 2020 6:51 PM UTC
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

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.
Tesla DeLorean
Tesla DeLoreanBest answer
Guru
Nov 22, 2020 7:01 PM UTC

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

2 replies

Tesla DeLorean
Tesla DeLoreanBest answer
Guru
Nov 22, 2020 7:01 PM UTC

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 (See Profile) Up vote any posts that you find helpful, it shows what's working..
Jsilv.1
Jsilv.1Author
Associate II
Nov 22, 2020 7:19 PM UTC

Problem seems solved.

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

__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
Delete_Sectors();