Question
Flash erase is not working properly on STM32L4A6RGT6
I'm trying to use flash erase to erase the address 0x08040000, its not erasing. I think I'm giving the values wrong for Bank and Pages.
#include "main.h"
#include "stdbool.h"
typedef enum {
NONE,
PREPARATION,
FLASH_ERASING,
FLASH_ERASE_DONE,
FLASH_WRITE_IN_PROGRESS,
FLASH_WRITE_DONE,
UPDATE_DONE,
} updateState_t;
#define NUM_PAGES 100
#define NUM_BYTES NUM_PAGES * FLASH_PAGE_SIZE
#define NUM_DOUBLEWORDS NUM_BYTES / 8
volatile updateState_t updateState = NONE;
void HAL_GPIO_EXTI_Callback(uint16_t pin) {
if (pin == GPIO_PIN_2) {
printf("Button is pressed");
if (updateState == NONE) {
updateState = PREPARATION;
}
}
void HAL_FLASH_EndOfOperationCallback(uint32_t ReturnValue) {
if (updateState == FLASH_ERASING && ReturnValue==0xffffffff) {
updateState = FLASH_ERASE_DONE;
} else if (updateState == FLASH_WRITE_IN_PROGRESS) {
updateState = FLASH_WRITE_DONE;
}
}
void toggleBankAndReset() {
FLASH_OBProgramInitTypeDef OBInit;
HAL_FLASH_Unlock();
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
HAL_FLASH_OB_Unlock();
HAL_FLASHEx_OBGetConfig(&OBInit);
OBInit.OptionType = OPTIONBYTE_USER;
OBInit.USERType = OB_USER_BFB2;
if (((OBInit.USERConfig) & (OB_BFB2_ENABLE)) == OB_BFB2_ENABLE) {
OBInit.USERConfig = OB_BFB2_DISABLE;
} else {
OBInit.USERConfig = OB_BFB2_ENABLE;
}
if (HAL_FLASHEx_OBProgram(&OBInit) != HAL_OK) {
// uint32_t errorCode = HAL_FLASH_GetError();
while (1) {
printf("1s delay is running::OB Program ");
HAL_Delay(1000);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
}
}
if (HAL_FLASH_OB_Launch() != HAL_OK) {
//uint32_t errorCode = HAL_FLASH_GetError();
while (1) {
printf("0.1s delay is running::OB launch ");
HAL_Delay(100);
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
}
}
HAL_FLASH_OB_Lock();
HAL_FLASH_Lock();
}
uint8_t getActiveBank() {
volatile uint32_t remap = READ_BIT(SYSCFG->MEMRMP, 0x1 << 8);
return remap == 0 ? 1 : 2;
}
}
int main(void)
{
uint8_t bank = getActiveBank();
uint32_t last = HAL_GetTick();
uint32_t delay;
if (bank == 1) {
printf("delay: 1000, when bank==1");
delay = 1000;
} else {
printf("delay: 500, else");
delay = 500;
}
while (1) {
uint32_t now = HAL_GetTick();
if (now - last > delay) {
HAL_GPIO_TogglePin(GPIOB, GPIO_PIN_5);
last = now;
}
switch (updateState) {
case NONE:
break;
case PREPARATION: {
FLASH_EraseInitTypeDef erase = { 0 };
erase.TypeErase = FLASH_TYPEERASE_PAGES;
erase.Banks = bank == 1 ? FLASH_BANK_2 : FLASH_BANK_1;
erase.NbPages = NUM_PAGES;
erase.Page = 0;
HAL_FLASH_Unlock();
HAL_StatusTypeDef status = HAL_FLASHEx_Erase_IT(&erase);
if (status != HAL_OK) {
// TODO error case
}
updateState = FLASH_ERASING;
}
break;
case FLASH_ERASING:
case FLASH_WRITE_IN_PROGRESS:
delay = 200;
// updateState = FLASH_ERASE_DONE;
break;
case FLASH_ERASE_DONE:
case FLASH_WRITE_DONE: {
delay = 50;
static size_t index = 0;
uint32_t dest = 0x08010000;
uint8_t *src = (uint8_t*) 0x08000000;
if (index < NUM_DOUBLEWORDS) {
uint64_t doubleword = *(uint64_t*) (src + (index * 8));
updateState = FLASH_WRITE_IN_PROGRESS;
HAL_StatusTypeDef progStatus;
progStatus= HAL_FLASH_Program_IT(
FLASH_TYPEPROGRAM_DOUBLEWORD, dest + index * 8, doubleword);
if (progStatus == HAL_OK)
index++;
} else {
updateState = UPDATE_DONE;
}
}
break;
case UPDATE_DONE:
toggleBankAndReset();
break;
}
}
}