cancel
Showing results for 
Search instead for 
Did you mean: 

[SOLVED] HAL _ERROR while trying to program FLASH on STM32F411RE device

Carlos Diaz R.
Associate III

Hi,

I'm writing a bootloader, the application binary is read from a SD card connected via SDIO and will be written into the SECTOR 2 of the micro controller (starts at 0x8008000 == APP_ADDRESS), the bootloader is stored in SECTOR 0 and SECTOR 1, starting from 0x8008000.

Here is the code where i erase from SECTOR 2 to SECTOR 7 and then try to program DWORDs (uint64_t) starting from 0x8008000, the SECTORs are erased successfully.

The problem i'm facing is that HAL_FLASH_Program doesn't returns, while trying to debug the problem i notices the data isn't being written into the selected Address and then the status is set to HAL_ERROR in FLASH_WaitForLastOperation inside the HAL_FLASH_Program function.

/* ***: Step 1: Init bootloader and Flash */
DBG_println("Step 1: Init bootloader and Flash");
 
/* ***: Step 2: Erase Flash */
DBG_println("Step 2: Erase Flash");
{
 /* Unlock the FLASH control register access */
HAL_FLASH_Unlock();
 
 __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR);
 
 // FLASH_VOLTAGE_RANGE_3: when the device voltage range is 2.7V to 3.6V
DBG_println("Borrando sector 2");
FLASH_Erase_Sector(FLASH_SECTOR_2, VOLTAGE_RANGE_3);
FLASH_WaitForLastOperation(1000);
DBG_println("Borrando sector 3");
FLASH_Erase_Sector(FLASH_SECTOR_3, VOLTAGE_RANGE_3);
FLASH_WaitForLastOperation(1000);
DBG_println("Borrando sector 4");
FLASH_Erase_Sector(FLASH_SECTOR_4, VOLTAGE_RANGE_3);
FLASH_WaitForLastOperation(1000);
DBG_println("Borrando sector 5");
FLASH_Erase_Sector(FLASH_SECTOR_5, VOLTAGE_RANGE_3);
FLASH_WaitForLastOperation(1000);
DBG_println("Borrando sector 6");
FLASH_Erase_Sector(FLASH_SECTOR_6, VOLTAGE_RANGE_3);
FLASH_WaitForLastOperation(1000);
DBG_println("Borrando sector 7");
FLASH_Erase_Sector(FLASH_SECTOR_7, VOLTAGE_RANGE_3);
FLASH_WaitForLastOperation(1000);
 
/* Lock the FLASH control register access */
HAL_FLASH_Lock();
}
 
/* ***: Step 3: Programming */
DBG_println("Step 3: Programming");
{
	  uint32_t address = APP_ADDRESS;
	  uint8_t buffer[8] = {0};
	  UINT bytes = 0;
 
	  retSD = f_open(&Wiggle_App_File, new_app_name, FA_READ);
	  FatFsError(retSD);
 
	  /* Note: If an erase operation in Flash memory also concerns data in the data or instruction cache,
	     you have to make sure that these data are rewritten before they are accessed during code
	     execution. If this cannot be done safely, it is recommended to flush the caches by setting the
	     DCRST and ICRST bits in the FLASH_CR register. */
	  __HAL_FLASH_DATA_CACHE_DISABLE();
	  __HAL_FLASH_INSTRUCTION_CACHE_DISABLE();
 
	  __HAL_FLASH_DATA_CACHE_RESET();
	  __HAL_FLASH_INSTRUCTION_CACHE_RESET();
	  __HAL_FLASH_INSTRUCTION_CACHE_ENABLE();
	  __HAL_FLASH_DATA_CACHE_ENABLE();
 
	  while (!f_eof(&App_File)) {
			  retSD = f_read(&App_File, buffer, sizeof buffer, &bytes);
			  if (FR_OK == retSD) {
				  FatFsError(retSD);
 
				  DBG_println("[0x%02X][0x%02X][0x%02X][0x%02X][0x%02X][0x%02X][0x%02X][0x%02X]",
				  buffer[0], buffer[1], buffer[2], buffer[3],
				  buffer[4], buffer[5], buffer[6], buffer[7]);
 
				  uint64_t data_to_write = (uint64_t) buffer[0] << 56 |
						  (uint64_t) buffer[1] << 48 |
						  (uint64_t) buffer[2] << 40 |
						  (uint64_t) buffer[3] << 32 |
						  (uint64_t) buffer[4] << 24 |
						  (uint64_t) buffer[5] << 16 |
						  (uint64_t) buffer[6] << 8 |
						  (uint64_t) buffer[7];
 
				  HAL_StatusTypeDef status = HAL_FLASH_Unlock();
				  DBG_println("Flash Unlock status: %d", status);
				  if (HAL_OK != status) {
					  continue;
				  }
 
				  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR | FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR);
				  DBG_println("Writting: 0x%016llX @ 0x%08lX", data_to_write, address);
				  HAL_StatusTypeDef flash_program_sts = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,
						  address, data_to_write);
				  DBG_println("Flash program status: %d", flash_program_sts);
				  if (HAL_OK == flash_program_sts) {
					  address += 8;
				  }
 
				  status = HAL_FLASH_Lock();
				  DBG_println("Flash Lock status: %d", status); 
			  } else {
				  FatFsError(retSD);
			  }
		  }
	 }

It is my first time writing a bootloader so I must be doing something silly, can you see something wrong?

I can upload the CubeMX project if nedded.

Regards,

Carlos

1 ACCEPTED SOLUTION

Accepted Solutions
Carlos Diaz R.
Associate III

I changed from FLASH_TYPEPROGRAM_DOUBLEWORD to FLASH_TYPEPROGRAM_WORD and the flash is programmed successfully, here's the relevant part of the code.

			  while (!f_eof(&Wiggle_App_File)) {
				  retSD = f_read(&Wiggle_App_File, buffer, sizeof buffer, &bytes);
				  if (FR_OK == retSD) {
					  FatFsError(retSD);
 
					  uint64_t data_to_write = (uint64_t) buffer[0] << 24 | (uint64_t) buffer[1] << 16 |
							  (uint64_t) buffer[2] << 8 | (uint64_t) buffer[3];
 
					  HAL_StatusTypeDef status = HAL_FLASH_Unlock();
					  if (HAL_OK != status) {
						  continue;
					  }
 
					  FLASH_FlushCaches();
 
					  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
							  FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR | FLASH_FLAG_PGPERR);
 
					  flash_program_sts = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data_to_write);
 
					  if (HAL_OK == flash_program_sts) {
						  address += 4;
					  }
 
					  status = HAL_FLASH_Lock();
				  } else {
					  FatFsError(retSD);
				  }
			  }

View solution in original post

1 REPLY 1
Carlos Diaz R.
Associate III

I changed from FLASH_TYPEPROGRAM_DOUBLEWORD to FLASH_TYPEPROGRAM_WORD and the flash is programmed successfully, here's the relevant part of the code.

			  while (!f_eof(&Wiggle_App_File)) {
				  retSD = f_read(&Wiggle_App_File, buffer, sizeof buffer, &bytes);
				  if (FR_OK == retSD) {
					  FatFsError(retSD);
 
					  uint64_t data_to_write = (uint64_t) buffer[0] << 24 | (uint64_t) buffer[1] << 16 |
							  (uint64_t) buffer[2] << 8 | (uint64_t) buffer[3];
 
					  HAL_StatusTypeDef status = HAL_FLASH_Unlock();
					  if (HAL_OK != status) {
						  continue;
					  }
 
					  FLASH_FlushCaches();
 
					  __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_EOP | FLASH_FLAG_OPERR | FLASH_FLAG_WRPERR |
							  FLASH_FLAG_PGAERR | FLASH_FLAG_PGSERR | FLASH_FLAG_PGPERR);
 
					  flash_program_sts = HAL_FLASH_Program(FLASH_TYPEPROGRAM_WORD, address, data_to_write);
 
					  if (HAL_OK == flash_program_sts) {
						  address += 4;
					  }
 
					  status = HAL_FLASH_Lock();
				  } else {
					  FatFsError(retSD);
				  }
			  }