qmk_firmware

QMK firmware for my keyboards (Corne, Sweep Ferris) and trackball (Ploopy Adept)
Log | Files | Refs | Submodules | LICENSE

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 }