logo

qmk_firmware

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

at32_dfu.c (2384B)


  1. // Copyright 2021-2023 QMK
  2. // Copyright 2023-2024 HorrorTroll <https://github.com/HorrorTroll>
  3. // Copyright 2023-2024 Zhaqian <https://github.com/zhaqian12>
  4. // SPDX-License-Identifier: GPL-2.0-or-later
  5. #include "bootloader.h"
  6. #include "util.h"
  7. #include <ch.h>
  8. #include <hal.h>
  9. #include "wait.h"
  10. #ifndef AT32_BOOTLOADER_RAM_SYMBOL
  11. # define AT32_BOOTLOADER_RAM_SYMBOL __ram0_end__
  12. #endif
  13. extern uint32_t AT32_BOOTLOADER_RAM_SYMBOL;
  14. /* This code should be checked whether it runs correctly on platforms */
  15. #define SYMVAL(sym) (uint32_t)(((uint8_t *)&(sym)) - ((uint8_t *)0))
  16. #define BOOTLOADER_MAGIC 0xDEADBEEF
  17. #define MAGIC_ADDR (unsigned long *)(SYMVAL(AT32_BOOTLOADER_RAM_SYMBOL) - 4)
  18. __attribute__((weak)) void bootloader_marker_enable(void) {
  19. uint32_t *marker = (uint32_t *)MAGIC_ADDR;
  20. *marker = BOOTLOADER_MAGIC; // set magic flag => reset handler will jump into boot loader
  21. }
  22. __attribute__((weak)) bool bootloader_marker_active(void) {
  23. const uint32_t *marker = (const uint32_t *)MAGIC_ADDR;
  24. return (*marker == BOOTLOADER_MAGIC) ? true : false;
  25. }
  26. __attribute__((weak)) void bootloader_marker_disable(void) {
  27. uint32_t *marker = (uint32_t *)MAGIC_ADDR;
  28. *marker = 0;
  29. }
  30. __attribute__((weak)) void bootloader_jump(void) {
  31. bootloader_marker_enable();
  32. NVIC_SystemReset();
  33. }
  34. __attribute__((weak)) void mcu_reset(void) {
  35. NVIC_SystemReset();
  36. }
  37. void enter_bootloader_mode_if_requested(void) {
  38. if (bootloader_marker_active()) {
  39. bootloader_marker_disable();
  40. struct system_memory_vector_t {
  41. uint32_t stack_top;
  42. void (*entrypoint)(void);
  43. };
  44. const struct system_memory_vector_t *bootloader = (const struct system_memory_vector_t *)(AT32_BOOTLOADER_ADDRESS);
  45. __disable_irq();
  46. #if defined(__MPU_PRESENT) && (__MPU_PRESENT == 1U)
  47. ARM_MPU_Disable();
  48. #endif
  49. SysTick->CTRL = 0;
  50. SysTick->VAL = 0;
  51. SysTick->LOAD = 0;
  52. // Clear interrupt enable and interrupt pending registers
  53. for (int i = 0; i < ARRAY_SIZE(NVIC->ICER); i++) {
  54. NVIC->ICER[i] = 0xFFFFFFFF;
  55. NVIC->ICPR[i] = 0xFFFFFFFF;
  56. }
  57. __set_CONTROL(0);
  58. __set_MSP(bootloader->stack_top);
  59. __enable_irq();
  60. // Jump to bootloader
  61. bootloader->entrypoint();
  62. while (true) {
  63. }
  64. }
  65. }