2019-05-08 08:24 AM
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
Solved! Go to Solution.
2019-05-09 11:10 AM
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);
}
}
2019-05-09 11:10 AM
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);
}
}