Skip to content

Commit

Permalink
Write and erase flash when the Internal RC Oscillator is off
Browse files Browse the repository at this point in the history
- By first enabling it
- This worked for me on STM32F103
- Quite likely not the best structure
- Willing to take instructions, or hand it over

Fixed the check to include HSIRDY alongside HSION
- When writing HSION, the HSIRDY takes some time to come up
- This may in theory have delays
- It is entirely proper to check the bits together; they are "ist & soll"
  • Loading branch information
vanrein committed Oct 25, 2023
1 parent 31c7fc6 commit e5be102
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 0 deletions.
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

0 comments on commit e5be102

Please sign in to comment.