I have a custom board with an STM32F103VE MCU. I can connect to it fine using ST-Link Utility, and I even had code downloaded to it a few times (in ST-Link Utility as well as CooCox), but today I started having problems erasing the MCU's internal flash memory.
When performing a mass erase (Target -> Erase Chip in ST-Link Utility), the log reads "Flash memory erased.", yet when reading back the memory, the old contents are still there, even after rebooting the MCU, reconnecting the ST-Link adapter, and even rebooting the computer. If I try to erase individual sectors (Target -> Erase Sectors... in ST-Link Utility), this is what I get in the output log having selected all sectors to erase:
17:55:27 : Flash page 0 @0x08000000 is not erased. Verify the memory protection.
17:55:27 : Flash page 1 @0x08000800 is not erased. Verify the memory protection.
17:55:28 : Flash page 2 @0x08001000 erased.
17:55:28 : Flash page 3 @0x08001800 erased.
17:55:28 : Flash page 4 @0x08002000 erased.
17:55:28 : Flash page 5 @0x08002800 erased.
17:55:28 : Flash page 6 @0x08003000 erased.
17:55:28 : Flash page 7 @0x08003800 erased.
17:55:29 : Flash page 8 @0x08004000 is not erased. Verify the memory protection.
17:55:29 : Flash page 9 @0x08004800 is not erased. Verify the memory protection.
17:55:33 : Flash page 33 @0x08010800 is not erased. Verify the memory protection.
17:55:33 : Flash page 34 @0x08011000 is not erased. Verify the memory protection.
17:55:33 : Flash page 35 @0x08011800 erased.
17:55:33 : Flash page 36 @0x08012000 erased.
17:56:07 : Flash page 254 @0x0807F000 erased.
17:56:07 : Flash page 255 @0x0807F800 erased.
Just to be clear, this is not an option bytes issue -- those related to memory protection are all clear ("No Protection"), and in fact when trying to update the option bytes, I get an error stating "Could not set Option bytes! Please reset the target and retry!"
It turns out that I only had code written to the first page (0x0800000 - 0x080007FF) and then to pages 8 through 34 (0x08004000 - 0x080117FF). So the pages that were supposedly erased were in fact blank to start with.
Now, as shown above, there is a problem erasing page 1 as well (0x08000800 - 0x08000FFF). Originally this was a blank page, which when attempting an erase as above indicated a successful erase, but I decided to perform an experiment that convinced me this is a hardware fault: I wrote a small .bin file starting at 0x08000800. The first few words from this 32-bit file are:
0x20000808 0x08000255 0x08000251 0x08000251 0x08000251 0x08000251 0x08000251 0x00000000 0x00000000 0x00000000 0x00000000 0x08000251 ...
Yet, after writing this to the originally blank page 1 and reading back from the memory, I get this:
0xFDFFEFFF 0xFBFFFBFF 0xFFFFFFFF 0xDFFFFEFF 0xFFFFFFFF 0xFFFFFFFF 0xFFFFFFFF 0xF7FFFFFF 0xFFFDFFFF 0xFFFFFBFF 0xFFFFFFFF 0xFFFFFFFF ...
From this moment on, when trying to erase page 1 (via Target -> Erase Sectors...), it reported a failure in this page, exactly as shown above.
With this in my mind, I have two questions:
Is this MCU irrevocably bricked indeed? This isn't just a question of penny-pinching, but this is a BGA MCU that was reflow soldered, and reworking it is not my idea of fun. Hence I'm open to any suggestions to try unbricking it.
If this is a hardware failure, how did it come about, so I can try to prevent it in the future? Here I should mention that this board has a weird power architecture, and due to some incorrectly soldered parts, it appears that it may have been subject to especially low voltages supplied from a coin cell (CR1220), which was fully discharged (from 3.0 V to 2.4 V) in the span of a few hours (normally it is powered from USB or a rechargeable Li-Ion battery). A second coin cell was put in place, and by the time I realized this power issue, it was already down to 2.7 V. I have a theory that the STM32 has some internal circuitry to generate the required programming voltage, but it needs a minimum voltage to work properly, and possibly it was subject to a lower voltage which overloaded and permanently damaged the circuit. Note that I have no data to back this up, it's just wild speculation.
EDIT: there is one detail I forgot to mention, which I don't think is the source of the issue, but perhaps it's worth mentioning: one of the last things I did before the MCU was bricked was to inadvertently program a .bin file at the wrong address (0x200 beyond the correct starting address) and hence it may have tried to write beyond the end of the flash memory (i.e. in addresses 0x08080000-0x080801FF). If anyone thinks this may be what eventually bricked the MCU, please let me know.