Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Write and erase flash when the Internal RC Oscillator is off #1348

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions inc/stm32.h
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,7 @@ enum stm32_chipids {
#define STM32WB_DBGMCU_APB1FZR1_WWDG_STOP 11
#define STM32WB_DBGMCU_APB1FZR1_IWDG_STOP 12

#define STM32F1_RCC_CR 0x40021000
#define STM32F1_RCC_AHBENR 0x40021014
#define STM32F1_RCC_DMAEN 0x00000003 // DMA2EN | DMA1EN

Expand Down
20 changes: 20 additions & 0 deletions src/stlink-lib/common_flash.c
Original file line number Diff line number Diff line change
Expand Up @@ -424,13 +424,17 @@ static void unlock_flash(stlink_t *sl) {
uint32_t key_reg, key2_reg = 0;
uint32_t flash_key1 = FLASH_KEY1;
uint32_t flash_key2 = FLASH_KEY2;
uint32_t clk_reg = 0;
uint32_t hsion = 0x00000001;
uint32_t hsirdy = 0x00000002;
/* The unlock sequence consists of 2 write cycles where 2 key values are
* written to the FLASH_KEYR register. An invalid sequence results in a
* definitive lock of the FPEC block until next reset.
*/

if (sl->flash_type == STM32_FLASH_TYPE_F0_F1_F3) {
key_reg = FLASH_KEYR;
clk_reg = STM32F1_RCC_CR;
} else if (sl->flash_type == STM32_FLASH_TYPE_F1_XL) {
key_reg = FLASH_KEYR;
key2_reg = FLASH_KEYR2;
Expand Down Expand Up @@ -468,6 +472,22 @@ static void unlock_flash(stlink_t *sl) {
return;
}

/* First make sure that the HSI is running, the internal RC clock.
* This is a requisite for flash erase and write.
*/
if (clk_reg) {
uint32_t oldcr;
stlink_read_debug32 (sl, clk_reg, &oldcr);
while (0 != ((hsion | hsirdy) & ~oldcr)) {
stlink_write_debug32 (sl, clk_reg, oldcr | hsion);
stlink_read_debug32 (sl, clk_reg, &oldcr);
}
} else {
WLOG("unsure about internal oscillator activity, flash write and erase may block\n");
}

/* Now unlock the flash itself.
*/
stlink_write_debug32(sl, key_reg, flash_key1);
stlink_write_debug32(sl, key_reg, flash_key2);

Expand Down
Loading