extra.c (2281B)
1 // Copyright 2025 Stefan Kerkmann (@karlk90) 2 // SPDX-License-Identifier: GPL-2.0-or-later 3 4 #include <hal.h> 5 6 #define FLASH_KEY1 0x45670123U 7 #define FLASH_KEY2 0xCDEF89ABU 8 #define FLASH_OPTKEY1 0x08192A3BU 9 #define FLASH_OPTKEY2 0x4C5D6E7FU 10 #define FLASH_OPTR_CLR_MASK (FLASH_OPTR_nBOOT_SEL) 11 #define FLASH_OPTR_SET_MASK (FLASH_OPTR_NRST_MODE_Msk) 12 13 static void wait_for_flash(void) { 14 while (READ_BIT(FLASH->SR, FLASH_SR_BSY1)) { 15 } 16 } 17 18 void __attribute__((constructor)) enable_boot0_and_nrst_pin(void) { 19 // Only apply on STM32G0x1 devices, see RM0444 Rev 6, Table 265: "DEV_ID 20 // and REV_ID field values." 21 switch (READ_BIT(DBG->IDCODE, DBG_IDCODE_DEV_ID)) { 22 case 0x467: // STM32G0B1xx and STM32G0C1xx 23 case 0x460: // STM32G071xx and STM32G081xx 24 case 0x456: // STM32G051xx and STM32G061xx 25 case 0x466: // STM32G041xx and STM32G031xx 26 break; 27 default: 28 return; 29 } 30 31 uint32_t optr = FLASH->OPTR; 32 33 // Make sure that: 34 // 1. legacy boot0 pin handling is enabled. 35 // OPTR[24] = 0 36 // 2. legacy nRST pin handling is enabled. 37 // OPTR[28:27] = 0b11 38 // To match the default behavior found in older (F0/F1/F3/F4) STM32 devices. 39 if (READ_BIT(optr, FLASH_OPTR_CLR_MASK) || (READ_BIT(optr, FLASH_OPTR_SET_MASK) != FLASH_OPTR_SET_MASK)) { 40 if (READ_BIT(FLASH->CR, FLASH_CR_LOCK)) { 41 WRITE_REG(FLASH->KEYR, FLASH_KEY1); 42 WRITE_REG(FLASH->KEYR, FLASH_KEY2); 43 while (READ_BIT(FLASH->CR, FLASH_CR_LOCK)) { 44 } 45 wait_for_flash(); 46 } 47 if (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK)) { 48 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY1); 49 WRITE_REG(FLASH->OPTKEYR, FLASH_OPTKEY2); 50 while (READ_BIT(FLASH->CR, FLASH_CR_OPTLOCK)) { 51 } 52 wait_for_flash(); 53 } 54 55 MODIFY_REG(FLASH->OPTR, FLASH_OPTR_CLR_MASK, FLASH_OPTR_SET_MASK); 56 wait_for_flash(); 57 58 SET_BIT(FLASH->CR, FLASH_CR_OPTSTRT); 59 wait_for_flash(); 60 61 CLEAR_BIT(FLASH->CR, FLASH_CR_OPTSTRT); 62 wait_for_flash(); 63 64 // Launch the option byte (re)loading, which resets the device. This 65 // should not return. 66 SET_BIT(FLASH->CR, FLASH_CR_OBL_LAUNCH); 67 } 68 }