stm32.c 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*
  2. * at32f4/stm32.c
  3. *
  4. * Core and peripheral registers.
  5. *
  6. * Written & released by Keir Fraser <keir.xen@gmail.com>
  7. *
  8. * This is free and unencumbered software released into the public domain.
  9. * See the file COPYING for more details, or visit <http://unlicense.org>.
  10. */
  11. unsigned int FLASH_PAGE_SIZE = 2048;
  12. unsigned int at32f4_series;
  13. static void clock_init(void)
  14. {
  15. uint32_t cfgr;
  16. if (at32f4_series == AT32F415) {
  17. /* Flash controller: reads require 4 wait states at 144MHz. */
  18. flash->acr = FLASH_ACR_PRFTBE | FLASH_ACR_LATENCY(4);
  19. }
  20. /* Start up the external oscillator. */
  21. rcc->cr |= RCC_CR_HSEON;
  22. while (!(rcc->cr & RCC_CR_HSERDY))
  23. cpu_relax();
  24. /* PLLs, scalers, muxes. */
  25. cfgr = (RCC_CFGR_PLLMUL_18 | /* PLL = 18*8MHz = 144MHz */
  26. RCC_CFGR_USBPSC_3 | /* USB = 144/3MHz = 48MHz */
  27. RCC_CFGR_PLLSRC_PREDIV1 |
  28. RCC_CFGR_ADCPRE_DIV8 |
  29. RCC_CFGR_APB2PSC_2 | /* APB2 = 144/2MHz = 72MHz */
  30. RCC_CFGR_APB1PSC_2); /* APB1 = 144/2MHz = 72MHz */
  31. switch (at32f4_series) {
  32. case AT32F403:
  33. cfgr |= RCC_CFGR_PLLRANGE_GT72MHZ;
  34. early_delay_ms(2);
  35. break;
  36. case AT32F415: {
  37. uint32_t rcc_pll = *RCC_PLL;
  38. rcc_pll &= ~(RCC_PLL_PLLCFGEN | RCC_PLL_FREF_MASK);
  39. rcc_pll |= RCC_PLL_FREF_8M;
  40. *RCC_PLL = rcc_pll;
  41. break;
  42. }
  43. }
  44. rcc->cfgr = cfgr;
  45. /* Enable and stabilise the PLL. */
  46. rcc->cr |= RCC_CR_PLLON;
  47. while (!(rcc->cr & RCC_CR_PLLRDY))
  48. cpu_relax();
  49. switch (at32f4_series) {
  50. case AT32F403:
  51. early_delay_us(200);
  52. break;
  53. case AT32F415:
  54. *RCC_MISC2 |= RCC_MISC2_AUTOSTEP_EN;
  55. break;
  56. }
  57. /* Switch to the externally-driven PLL for system clock. */
  58. rcc->cfgr |= RCC_CFGR_SW_PLL;
  59. while ((rcc->cfgr & RCC_CFGR_SWS_MASK) != RCC_CFGR_SWS_PLL)
  60. cpu_relax();
  61. switch (at32f4_series) {
  62. case AT32F403:
  63. early_delay_us(200);
  64. break;
  65. case AT32F415:
  66. *RCC_MISC2 &= ~RCC_MISC2_AUTOSTEP_EN;
  67. break;
  68. }
  69. /* Internal oscillator no longer needed. */
  70. rcc->cr &= ~RCC_CR_HSION;
  71. }
  72. static void peripheral_init(void)
  73. {
  74. /* Enable basic GPIO and AFIO clocks, and DMA. */
  75. rcc->apb1enr = 0;
  76. rcc->apb2enr = (RCC_APB2ENR_IOPAEN |
  77. RCC_APB2ENR_IOPBEN |
  78. RCC_APB2ENR_IOPCEN |
  79. RCC_APB2ENR_IOPFEN |
  80. RCC_APB2ENR_AFIOEN);
  81. rcc->ahbenr = RCC_AHBENR_DMA1EN;
  82. /* Reclaim JTAG pins. */
  83. afio->mapr = AFIO_MAPR_SWJ_ON_JTAG_OFF;
  84. gpio_configure_pin(gpioa, 15, GPI_floating);
  85. gpio_configure_pin(gpiob, 3, GPI_floating);
  86. gpio_configure_pin(gpiob, 4, GPI_floating);
  87. }
  88. static void identify_mcu(void)
  89. {
  90. unsigned int flash_kb = *(uint16_t *)0x1ffff7e0;
  91. if (flash_kb <= 128)
  92. FLASH_PAGE_SIZE = 1024;
  93. at32f4_series = *(uint8_t *)0x1ffff7f3; /* UID[95:88] */
  94. switch (at32f4_series) {
  95. case AT32F403:
  96. case AT32F415:
  97. break;
  98. default:
  99. early_fatal(4);
  100. }
  101. }
  102. void stm32_init(void)
  103. {
  104. cortex_init();
  105. identify_mcu();
  106. identify_board_config();
  107. clock_init();
  108. peripheral_init();
  109. cpu_sync();
  110. }
  111. void gpio_configure_pin(GPIO gpio, unsigned int pin, unsigned int mode)
  112. {
  113. gpio_write_pin(gpio, pin, mode >> 4);
  114. mode &= 0xfu;
  115. if (pin >= 8) {
  116. pin -= 8;
  117. gpio->crh = (gpio->crh & ~(0xfu<<(pin<<2))) | (mode<<(pin<<2));
  118. } else {
  119. gpio->crl = (gpio->crl & ~(0xfu<<(pin<<2))) | (mode<<(pin<<2));
  120. }
  121. }
  122. /*
  123. * Local variables:
  124. * mode: C
  125. * c-file-style: "Linux"
  126. * c-basic-offset: 4
  127. * tab-width: 4
  128. * indent-tabs-mode: nil
  129. * End:
  130. */