Strange problem writing flash on STM32L4xx
I use a flash-filing system I wrong many years ago, and I am adapting it to STM32L4. The first obvious difference is that there is no half-word write and it is only possible to write 8-byte DWords to DWord aligned addresses whose value is currently 0xFFFFFFFFFFFFFFFF.
This is a pain because it means I can't spoof a half-word write, or clear individual bits, but nevertheless I converted it all to be based on 8-bytes even though it is a little wasteful.
When I write a new record, I set a pointer in the previous record to point to this new record. There is an 8-byte 0xFFFFFFFFFFFFFFFF on an 8-byte boundary reserved in the original record for this. When I try to write to this, I get a flash error 0xA8 which appears to be:
programming error, address error, sequence error
However the address is correctly aligned, the 64-bits are all set to 1 and flash lock/unlock sequences are all good.
I have run sequences filling every other address with a value, and then filling the the remaining addresses with values but had no errors. However when my library tries to write to this reserved space to save the address of the new record I get the error.
Rebooting and leaving the flash in the same state, I test directly writing to the address without the complexity of the library and I am unable to.
I wonder if this is related to the error detection?
Any ideas would be most welcome.
Thanks
example failing code:
u64_t dword = 0x0000000008060c58; u32_t write_address = 0x08060010; volatile u64_t flash_val = *(u64_t *)write_address; // flash_val confirms that 0xFFFFFFFFFFFFFFFF is at 0x08060010 volatile HAL_StatusTypeDef status = HAL_OK; status = HAL_FLASH_Unlock(); __HAL_FLASH_CLEAR_FLAG(FLASH_FLAG_ALL_ERRORS); status = HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, write_address, dword); // status is set to HAL_ERROR status = HAL_FLASH_Lock();
-
Finally got to the bottom of this, so I'll update in-case anyone has the same problem.
The problem was being caused by the blank DWord actually not being blank as far as the chip was concerned, I had previously written 0xFFFFFFFFFFFFFFFF to it. This fact was presumably recorded in the ECC bits and was the reason the chip would only allow me to write 0x0 to it afterwards.
Fix was to check for a "blank" right in my flash library thus:
BOOL flash_program_double(u32_t address, u64_t data) { BOOL ret = FALSE; // Don't write all FFs as this will not allow them to be cleared afterwards if (data == 0xFFFFFFFFFFFFFFFF) { return (TRUE); } ret = (HAL_FLASH_Program(FLASH_TYPEPROGRAM_DOUBLEWORD, address, data) == HAL_OK); return (ret); }
Please sign in to leave a comment.
Comments
1 comment