2024-03-09 05:57 AM
Hello ST Community,
I'm currently facing a challenging issue with my STM32L476RET6 where I'm unable to erase a specific page in the flash memory. Despite the HAL_FLASHEx_Erase() function returning HAL_OK, indicating the erase operation was supposedly successful, the bytes at the specified memory location are not set to 0xFF as expected. I've confirmed this by checking the memory location with STM32CubeProgrammer.
Environment:
MCU: STM32L476RET6
IDE: STM32CubeIDE
OS: Windows 10
Here's the function where I'm encountering the issue:
HAL_StatusTypeDef set_update_flag(void) {
// Unlock the Flash to enable the flash control register access
HAL_StatusTypeDef status = HAL_FLASH_Unlock();
if (status != HAL_OK) {
// Unlock failed, handle accordingly
return status;
}
// Define the page and bank for the erase operation
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PageError = 0;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Banks = FLASH_BANK_1;
EraseInitStruct.Page = 255; // Targeting the last page for the erase operation
EraseInitStruct.NbPages = 1;
// Erase the page
status = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
if (status != HAL_OK) {
// Erase failed, handle accordingly
HAL_FLASH_Lock(); // Make sure to lock the flash again before returning
return status;
}
// Set the update flag to 1
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, UPDATE_FLAG_ADDRESS, 0x0000000100000001);
if (status != HAL_OK) {
// Program failed, handle accordingly
HAL_FLASH_Lock(); // Make sure to lock the flash again before returning
return status;
}
HAL_FLASH_Lock(); // Lock the Flash to disable the flash control register access
return HAL_OK;
}
Interestingly, there's no HAL_ERROR after calling HAL_FLASHEx_Erase(), but PageError returns 0xFFFFFFFF. This leads to a HAL_ERROR when attempting to write to the memory location afterwards with HAL_FLASH_Program().
I've previously had this functionality working, but it's currently not behaving as expected, and I'm at a bit of a loss. I've checked and re-checked the page number and confirmed that the flash is being unlocked successfully. The same goes for the flash lock at the end of the operation.
Has anyone encountered a similar issue or have insights into what might be going wrong? Any suggestions or advice would be greatly appreciated.
Thank you in advance for your help!
Adrian.
Solved! Go to Solution.
2024-03-09 01:57 PM
Hi @TDK ,
Thank you so much for your advice regarding the dual-bank configuration and the suggestion to inspect the option bytes using STM32CubeProgrammer. I took your recommendations on board and delved into CubeProgrammer to get a better understanding of my STM32L476's configuration. Here's what I discovered and how it led me to a solution:
Dual-Bank Configuration: As you mentioned, the L476 can indeed operate in both single and dual-bank modes. Upon inspection, I confirmed that the DualBank option was indeed checked, validating that my device was set up for dual-bank operation, with each bank presumably starting its page numbering from 0.
BFB2 Setting: I also noted that the BFB2 option was unchecked, which aligns with the dual-bank boot being disabled, and the microcontroller is set to boot from the main flash memory as per the standard booting procedure.
Write Protection: I checked the write protection settings (WRP1A_END and WRP1B_END), and both were set to 0x0, indicating that write protection wasn't the cause of my issue, as no pages were write-protected.
Given these insights, particularly the confirmation of dual-bank operation with independent page numbering, I revisited my flash erase code. Initially, I had been trying to erase page 255 (EraseInitStruct.Page = 255;), working under the assumption that the pages were numbered sequentially across the two banks. However, understanding that each bank starts its page numbering from 0, I realized that page 255 would be outside the range of the first bank's pages.
I adjusted the page number to 127 (EraseInitStruct.Page = 127;), aiming to target the last page of the first bank, considering the dual-bank setup. This adjustment proved to be the solution, and the erase operation was successful, allowing me to proceed with setting the update flag as intended.
Please see my amended code:
HAL_StatusTypeDef set_update_flag(void) {
// Unlock the Flash to enable the flash control register access
HAL_StatusTypeDef status = HAL_FLASH_Unlock();
if (status != HAL_OK) {
// Unlock failed, handle accordingly
return status;
}
// Define the page and bank for the erase operation
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PageError = 0x0;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Banks = FLASH_BANK_2;
EraseInitStruct.Page = 127;
EraseInitStruct.NbPages = 1;
// Erase the page
status = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
if (status != HAL_OK) {
// Erase failed, handle accordingly
HAL_FLASH_Lock(); // Make sure to lock the flash again before returning
// Use PageError to determine the page that caused the error if needed
return status;
}
// Set the update flag to 1
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, UPDATE_FLAG_ADDRESS, 0x0000000100000001);
if (status != HAL_OK) {
// Program failed, handle accordingly
HAL_FLASH_Lock(); // Make sure to lock the flash again before returning
return status;
}
// Lock the Flash to disable the flash control register access
HAL_FLASH_Lock();
return HAL_OK; // Return HAL_OK if the entire operation was successful
}
Your guidance was instrumental in helping me navigate this issue, and greatly appreciate.
Many thanks,
Adrian.
2024-03-09 06:48 AM
Let's get a bit more specific.
> at the specified memory location are not set to 0xFF as expected. I've confirmed this by checking the memory location with STM32CubeProgrammer.
What memory location are you looking at? What values are you seeing?
Are you in dual bank mode?
Are the banks write protected by option bytes?
2024-03-09 07:53 AM
Hi @TDK
Hi,
Thank you for reaching out and helping me troubleshoot this issue.
Memory Location and Values:
#define UPDATE_FLAG_ADDRESS 0x0807FFF0
Cube Version and Regression Testing:
Single Bank vs. Dual Bank:
Write Protection:
I appreciate your insights and am looking forward to any further advice you might have.
Adrian.
2024-03-09 08:40 AM - edited 2024-03-09 08:41 AM
> Single Bank vs. Dual Bank:
The L476 can operate in both modes. Look at the DUALBANK option bit to find out which one it's in. You can do this within STM32CubeProgrammer on the OB tab on the left. By default, the chip operates in dual bank mode.
You can also view the write protect option bytes from there as well.
Also you should probably ensure BFB2=0.
2024-03-09 01:57 PM
Hi @TDK ,
Thank you so much for your advice regarding the dual-bank configuration and the suggestion to inspect the option bytes using STM32CubeProgrammer. I took your recommendations on board and delved into CubeProgrammer to get a better understanding of my STM32L476's configuration. Here's what I discovered and how it led me to a solution:
Dual-Bank Configuration: As you mentioned, the L476 can indeed operate in both single and dual-bank modes. Upon inspection, I confirmed that the DualBank option was indeed checked, validating that my device was set up for dual-bank operation, with each bank presumably starting its page numbering from 0.
BFB2 Setting: I also noted that the BFB2 option was unchecked, which aligns with the dual-bank boot being disabled, and the microcontroller is set to boot from the main flash memory as per the standard booting procedure.
Write Protection: I checked the write protection settings (WRP1A_END and WRP1B_END), and both were set to 0x0, indicating that write protection wasn't the cause of my issue, as no pages were write-protected.
Given these insights, particularly the confirmation of dual-bank operation with independent page numbering, I revisited my flash erase code. Initially, I had been trying to erase page 255 (EraseInitStruct.Page = 255;), working under the assumption that the pages were numbered sequentially across the two banks. However, understanding that each bank starts its page numbering from 0, I realized that page 255 would be outside the range of the first bank's pages.
I adjusted the page number to 127 (EraseInitStruct.Page = 127;), aiming to target the last page of the first bank, considering the dual-bank setup. This adjustment proved to be the solution, and the erase operation was successful, allowing me to proceed with setting the update flag as intended.
Please see my amended code:
HAL_StatusTypeDef set_update_flag(void) {
// Unlock the Flash to enable the flash control register access
HAL_StatusTypeDef status = HAL_FLASH_Unlock();
if (status != HAL_OK) {
// Unlock failed, handle accordingly
return status;
}
// Define the page and bank for the erase operation
FLASH_EraseInitTypeDef EraseInitStruct;
uint32_t PageError = 0x0;
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Banks = FLASH_BANK_2;
EraseInitStruct.Page = 127;
EraseInitStruct.NbPages = 1;
// Erase the page
status = HAL_FLASHEx_Erase(&EraseInitStruct, &PageError);
if (status != HAL_OK) {
// Erase failed, handle accordingly
HAL_FLASH_Lock(); // Make sure to lock the flash again before returning
// Use PageError to determine the page that caused the error if needed
return status;
}
// Set the update flag to 1
status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, UPDATE_FLAG_ADDRESS, 0x0000000100000001);
if (status != HAL_OK) {
// Program failed, handle accordingly
HAL_FLASH_Lock(); // Make sure to lock the flash again before returning
return status;
}
// Lock the Flash to disable the flash control register access
HAL_FLASH_Lock();
return HAL_OK; // Return HAL_OK if the entire operation was successful
}
Your guidance was instrumental in helping me navigate this issue, and greatly appreciate.
Many thanks,
Adrian.