logo

qmk_firmware

custom branch of QMK firmware git clone https://anongit.hacktivis.me/git/qmk_firmware.git

extra.c (2281B)


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