fix(flash): unlock flash unconditionally for clone STM32F103 chips#12
Open
shaiku wants to merge 1 commit into
Open
fix(flash): unlock flash unconditionally for clone STM32F103 chips#12shaiku wants to merge 1 commit into
shaiku wants to merge 1 commit into
Conversation
On certain clone STM32F103 devices (chips that correctly report
DBGMCU_IDCODE = 0x10006412 but have a non-standard flash controller),
FLASH_CR.LOCK reads as 0 after reset even though the flash controller
is still locked in hardware until the correct key sequence is written
to FLASH_KEYR.
The previous conditional unlock:
if (READ_BIT(FLASH->CR, FLASH_CR_LOCK)) {
WRITE_REG(FLASH->KEYR, FLASH_KEY1);
WRITE_REG(FLASH->KEYR, FLASH_KEY2);
}
silently skipped the unlock sequence on these devices, causing every
subsequent erase and write to do nothing. The bootloader still
reported success because the checksum is computed over the received
USB data, not the actual flash contents.
Fix: write the unlock keys unconditionally, matching the behaviour of
STM32CubeProgrammer's 0x412.stldr flash algorithm, which also writes
the keys without checking LOCK first. Writing the correct keys when
the flash is already unlocked is a documented safe no-op on genuine
STM32F1 silicon (RM0008 rev 21, section 3.3.3).
Also clear FLASH_SR error flags (PGERR, WRPRTERR, EOP) before each
page operation, again matching CubeProgrammer's Init() sequence, to
ensure a clean controller state if a previous operation left an error
flag set.
Tested on a clone device (DBGMCU_IDCODE 0x10006412, WRPR 0xFFFFFFFF,
no read protection) where tkg-flash previously reported "1 sectors
written / no checksum error" but left flash completely unprogrammed.
After this fix the bootloader programs and jumps to user code correctly.
Author
|
The backstory on this is I bought a batch of STM32F103C6T6 fake blue pills and none of the USB bootloaders would work correctly for various reasons. Yours has the additional initialization code that my chips seem to require (their POR behavior is not accurate), and tkg-flash reported success, but the bootloader failed to actually write data to flash. STM32CubeProgrammer works, however, so I disassembled 0x412.stldr and compared the flash unlock logic to yours. These are the only differences and these changes are what made your bootloader actually work on my silicon. It should be perfectly acceptable since it is the exact same logic ST themselves use to program STM32F1 parts. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
On certain clone STM32F103 devices (chips that correctly report DBGMCU_IDCODE = 0x10006412 but have a non-standard flash controller), FLASH_CR.LOCK reads as 0 after reset even though the flash controller is still locked in hardware until the correct key sequence is written to FLASH_KEYR.
The previous conditional unlock:
silently skipped the unlock sequence on these devices, causing every subsequent erase and write to do nothing. The bootloader still reported success because the checksum is computed over the received USB data, not the actual flash contents.
Fix: write the unlock keys unconditionally, matching the behaviour of STM32CubeProgrammer's 0x412.stldr flash algorithm, which also writes the keys without checking LOCK first. Writing the correct keys when the flash is already unlocked is a documented safe no-op on genuine STM32F1 silicon (RM0008 rev 21, section 3.3.3).
Also clear FLASH_SR error flags (PGERR, WRPRTERR, EOP) before each page operation, again matching CubeProgrammer's Init() sequence, to ensure a clean controller state if a previous operation left an error flag set.
Tested on a clone device (DBGMCU_IDCODE 0x10006412, WRPR 0xFFFFFFFF, no read protection) where tkg-flash previously reported "1 sectors written / no checksum error" but left flash completely unprogrammed. After this fix the bootloader programs and jumps to user code correctly.