The L4 series erases flash using pages (or banks, if you do a full erase). But I'm having some problem writing after doing page erases, and I'm not sure why.
Just to outline the objective I am storing 6 values starting at 0x08080000 (Page 256) then I am storing more values from 0x08080800) (page 257) to 0x08085800 (page 267)
There is a single function that I use to erase/write the values at page 256:
void write_bias_flash(int16_t biases[]) {
uint16_t *flash_biases = (uint16_t*) (ADDR_FLASH_PAGE_256);
static FLASH_EraseInitTypeDef EraseInitStruct;
Address = ADDR_FLASH_PAGE_256;
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = 0;
EraseInitStruct.Banks = FLASH_BANK_2;
EraseInitStruct.NbPages = 1;
HAL_FLASH_Unlock();
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
serprintf("Error erasing biases at address: 0x%x", Address);
}
for (int8_t bias = 0; bias < 6; bias++) {
if (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD,
Address + bias * sizeof(uint64_t), (uint64_t) biases[bias])
!= HAL_OK)
serprintf("Error writing biases to flash.");
}
HAL_FLASH_Lock();
serprintf("Biases stored in flash.");
}
This work great. No issues.
I have two functions I use to erase/write the data starting at 0x08080800) (page 257):
void Erase_TM_Flash() {
uint8_t *flash = (uint8_t*) (FLASH_USER_START_ADDR);
uint8_t *b = (uint16_t*) (ADDR_FLASH_PAGE_256);
static FLASH_EraseInitTypeDef EraseInitStruct;
Address = FLASH_USER_START_ADDR;
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_PAGES;
EraseInitStruct.Page = 1;
EraseInitStruct.NbPages = 255;
EraseInitStruct.Banks = FLASH_BANK_2;
HAL_FLASH_Unlock();
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
serprintf("Error erasing biases at address: 0x%x", Address);
}
HAL_FLASH_Lock();
for (uint16_t i = 0; i< (FLASH_ROW_SIZE * sizeof(uint64_t))*255; i++)
{
if ((uint16_t) *(flash+i) != 255) {
serprintf("0x%x is not erased (%i)", flash+i, (uint16_t) *(flash+i));
}
}
}
void Save_to_Flash(uint32_t *data) {
uint32_t src_addr = (uint32_t) data;
Erase_TM_Flash();
serprintf("Saving to flash...");
HAL_StatusTypeDef HAL_STATUS;
HAL_FLASH_Unlock();
Address = FLASH_USER_START_ADDR;
while (Address < (FLASH_USER_END_ADDR - (FLASH_ROW_SIZE * sizeof(uint64_t)))) {
HAL_STATUS = HAL_FLASH_Program(FLASH_TYPEPROGRAM_FAST, Address, (uint64_t) src_addr);
if (HAL_STATUS == HAL_OK) {
Address = Addres+ (FLASH_ROW_SIZE * sizeof(uint64_t));
src_addr = src_addr + (FLASH_ROW_SIZE * sizeof(uint64_t));
} else {
serprintf("Error writing flash at address 0x%x. (%i)", Address, HAL_STATUS);
Address = Address + (FLASH_ROW_SIZE * sizeof(uint64_t));
src_addr = src_addr + (FLASH_ROW_SIZE * sizeof(uint64_t));
}
}
HAL_FLASH_Lock();
serprintf("Done");
}
The erase works fine. I verify the values in the debugger (and in the code I check for non-erased pages). But when the saving occurs:
Error writing flash at address 0x8080800. (1)
Error writing flash at address 0x8080900. (1)
Error writing flash at address 0x8080a00. (1)
Error writing flash at address 0x8080b00. (1)
And so on through all the remaining pages.
However, if I erase the entire flash:
void Erase_Flash() {
serprintf("Erasing flash...");
HAL_FLASH_Unlock();
/* Clear OPTVERR bit set on virgin samples */
__HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_OPTVERR);
/* Fill EraseInit structure*/
EraseInitStruct.TypeErase = FLASH_TYPEERASE_MASSERASE;
EraseInitStruct.Banks = FLASH_BANK_2;
if (HAL_FLASHEx_Erase(&EraseInitStruct, &PAGEError) != HAL_OK) {
serprintf("Error erasing flash.");
}
HAL_FLASH_Lock();
serprintf("Done.");
}
Then the writing works like a charm. HAL_STATUS = 1, which according to the code I found is HAL_ERROR = 0x01U, which isn't entirely helpful.
I am not sure what the difference in, but I am hoping another set of eye on my erasure might reveal the issue.
Thanks!