system_stm32.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604
  1. /*
  2. * This file is part of the MicroPython project, http://micropython.org/
  3. *
  4. * Taken from ST Cube library and modified. See below for original header.
  5. *
  6. * The MIT License (MIT)
  7. *
  8. * Copyright (c) 2013, 2014 Damien P. George
  9. *
  10. * Permission is hereby granted, free of charge, to any person obtaining a copy
  11. * of this software and associated documentation files (the "Software"), to deal
  12. * in the Software without restriction, including without limitation the rights
  13. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  14. * copies of the Software, and to permit persons to whom the Software is
  15. * furnished to do so, subject to the following conditions:
  16. *
  17. * The above copyright notice and this permission notice shall be included in
  18. * all copies or substantial portions of the Software.
  19. *
  20. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  21. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  22. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  23. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  24. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  25. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  26. * THE SOFTWARE.
  27. */
  28. /**
  29. ******************************************************************************
  30. * @file system_stm32.c
  31. * @author MCD Application Team
  32. * @version V1.0.1
  33. * @date 26-February-2014
  34. * @brief CMSIS Cortex-M4/M7 Device Peripheral Access Layer System Source File.
  35. *
  36. * This file provides two functions and one global variable to be called from
  37. * user application:
  38. * - SystemInit(): This function is called at startup just after reset and
  39. * before branch to main program. This call is made inside
  40. * the "startup_stm32.s" file.
  41. *
  42. * - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
  43. * by the user application to setup the SysTick
  44. * timer or configure other parameters.
  45. *
  46. *
  47. ******************************************************************************
  48. * @attention
  49. *
  50. * <h2><center>&copy; COPYRIGHT 2014 STMicroelectronics</center></h2>
  51. *
  52. * Redistribution and use in source and binary forms, with or without modification,
  53. * are permitted provided that the following conditions are met:
  54. * 1. Redistributions of source code must retain the above copyright notice,
  55. * this list of conditions and the following disclaimer.
  56. * 2. Redistributions in binary form must reproduce the above copyright notice,
  57. * this list of conditions and the following disclaimer in the documentation
  58. * and/or other materials provided with the distribution.
  59. * 3. Neither the name of STMicroelectronics nor the names of its contributors
  60. * may be used to endorse or promote products derived from this software
  61. * without specific prior written permission.
  62. *
  63. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
  64. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  65. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  66. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
  67. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  68. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
  69. * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
  70. * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
  71. * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  72. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  73. *
  74. ******************************************************************************
  75. */
  76. /** @addtogroup CMSIS
  77. * @{
  78. */
  79. /** @addtogroup stm32fxxx_system
  80. * @{
  81. */
  82. /** @addtogroup STM32Fxxx_System_Private_Includes
  83. * @{
  84. */
  85. #include "py/mphal.h"
  86. void __fatal_error(const char *msg);
  87. /**
  88. * @}
  89. */
  90. /** @addtogroup STM32Fxxx_System_Private_TypesDefinitions
  91. * @{
  92. */
  93. /**
  94. * @}
  95. */
  96. /** @addtogroup STM32Fxxx_System_Private_Defines
  97. * @{
  98. */
  99. #if defined(STM32F4) || defined(STM32F7)
  100. #define CONFIG_RCC_CR_1ST (RCC_CR_HSION)
  101. #define CONFIG_RCC_CR_2ND (RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_PLLON)
  102. #define CONFIG_RCC_PLLCFGR (0x24003010)
  103. #if defined(STM32F4)
  104. const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
  105. const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
  106. #elif defined(STM32F7)
  107. const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
  108. const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
  109. #endif
  110. #elif defined(STM32L4)
  111. #define CONFIG_RCC_CR_1ST (RCC_CR_MSION)
  112. #define CONFIG_RCC_CR_2ND (RCC_CR_HSEON | RCC_CR_CSSON | RCC_CR_HSION | RCC_CR_PLLON)
  113. #define CONFIG_RCC_PLLCFGR (0x00001000)
  114. /*
  115. * FIXME Do not know why I have to define these arrays here! they should be defined in the
  116. * hal_rcc-file!!
  117. *
  118. */
  119. const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
  120. const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
  121. const uint32_t MSIRangeTable[12] = {100000, 200000, 400000, 800000, 1000000, 2000000, \
  122. 4000000, 8000000, 16000000, 24000000, 32000000, 48000000};
  123. #elif defined(STM32H7)
  124. #define CONFIG_RCC_CR_1ST (RCC_CR_HSION)
  125. #define CONFIG_RCC_CR_2ND (~0xEAF6ED7F)
  126. #define CONFIG_RCC_PLLCFGR (0x00000000)
  127. #define SRAM_BASE D1_AXISRAM_BASE
  128. #define FLASH_BASE FLASH_BANK1_BASE
  129. uint32_t SystemD2Clock = 64000000;
  130. const uint8_t D1CorePrescTable[16] = {0, 0, 0, 0, 1, 2, 3, 4, 1, 2, 3, 4, 6, 7, 8, 9};
  131. #else
  132. #error Unknown processor
  133. #endif
  134. /************************* Miscellaneous Configuration ************************/
  135. /*!< Uncomment the following line if you need to relocate your vector Table in
  136. Internal SRAM. */
  137. /* #define VECT_TAB_SRAM */
  138. #define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
  139. This value must be a multiple of 0x200. */
  140. /******************************************************************************/
  141. /**
  142. * @}
  143. */
  144. /** @addtogroup STM32Fxxx_System_Private_Macros
  145. * @{
  146. */
  147. /**
  148. * @}
  149. */
  150. /** @addtogroup STM32Fxxx_System_Private_Variables
  151. * @{
  152. */
  153. /* This variable is updated in three ways:
  154. 1) by calling CMSIS function SystemCoreClockUpdate()
  155. 2) by calling HAL API function HAL_RCC_GetHCLKFreq()
  156. 3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
  157. Note: If you use this function to configure the system clock; then there
  158. is no need to call the 2 first functions listed above, since SystemCoreClock
  159. variable is updated automatically.
  160. */
  161. uint32_t SystemCoreClock = 16000000;
  162. /**
  163. * @}
  164. */
  165. /** @addtogroup STM32Fxxx_System_Private_FunctionPrototypes
  166. * @{
  167. */
  168. /**
  169. * @}
  170. */
  171. /** @addtogroup STM32Fxxx_System_Private_Functions
  172. * @{
  173. */
  174. /**
  175. * @brief Setup the microcontroller system
  176. * Initialize the FPU setting, vector table location and External memory
  177. * configuration.
  178. * @param None
  179. * @retval None
  180. */
  181. void SystemInit(void)
  182. {
  183. /* FPU settings ------------------------------------------------------------*/
  184. #if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
  185. SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
  186. #endif
  187. /* Reset the RCC clock configuration to the default reset state ------------*/
  188. /* Set configured startup clk source */
  189. RCC->CR |= CONFIG_RCC_CR_1ST;
  190. /* Reset CFGR register */
  191. RCC->CFGR = 0x00000000;
  192. /* Reset HSEON, CSSON and PLLON bits */
  193. RCC->CR &= ~ CONFIG_RCC_CR_2ND;
  194. /* Reset PLLCFGR register */
  195. RCC->PLLCFGR = CONFIG_RCC_PLLCFGR;
  196. #if defined(STM32H7)
  197. /* Reset D1CFGR register */
  198. RCC->D1CFGR = 0x00000000;
  199. /* Reset D2CFGR register */
  200. RCC->D2CFGR = 0x00000000;
  201. /* Reset D3CFGR register */
  202. RCC->D3CFGR = 0x00000000;
  203. /* Reset PLLCKSELR register */
  204. RCC->PLLCKSELR = 0x00000000;
  205. /* Reset PLL1DIVR register */
  206. RCC->PLL1DIVR = 0x00000000;
  207. /* Reset PLL1FRACR register */
  208. RCC->PLL1FRACR = 0x00000000;
  209. /* Reset PLL2DIVR register */
  210. RCC->PLL2DIVR = 0x00000000;
  211. /* Reset PLL2FRACR register */
  212. RCC->PLL2FRACR = 0x00000000;
  213. /* Reset PLL3DIVR register */
  214. RCC->PLL3DIVR = 0x00000000;
  215. /* Reset PLL3FRACR register */
  216. RCC->PLL3FRACR = 0x00000000;
  217. #endif
  218. /* Reset HSEBYP bit */
  219. RCC->CR &= (uint32_t)0xFFFBFFFF;
  220. /* Disable all interrupts */
  221. #if defined(STM32F4) || defined(STM32F7)
  222. RCC->CIR = 0x00000000;
  223. #elif defined(STM32L4) || defined(STM32H7)
  224. RCC->CIER = 0x00000000;
  225. #endif
  226. #if defined(STM32H7)
  227. /* Change the switch matrix read issuing capability to 1 for the AXI SRAM target (Target 7) */
  228. *((__IO uint32_t*)0x51008108) = 0x00000001;
  229. #endif
  230. /* Configure the Vector Table location add offset address ------------------*/
  231. #ifdef MICROPY_HW_VTOR
  232. SCB->VTOR = MICROPY_HW_VTOR;
  233. #else
  234. #ifdef VECT_TAB_SRAM
  235. SCB->VTOR = SRAM1_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
  236. #else
  237. SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
  238. #endif
  239. #endif
  240. /* dpgeorge: enable 8-byte stack alignment for IRQ handlers, in accord with EABI */
  241. SCB->CCR |= SCB_CCR_STKALIGN_Msk;
  242. }
  243. /**
  244. * @brief System Clock Configuration
  245. *
  246. * The system Clock is configured for F4/F7 as follows:
  247. * System Clock source = PLL (HSE)
  248. * SYSCLK(Hz) = 168000000
  249. * HCLK(Hz) = 168000000
  250. * AHB Prescaler = 1
  251. * APB1 Prescaler = 4
  252. * APB2 Prescaler = 2
  253. * HSE Frequency(Hz) = HSE_VALUE
  254. * PLL_M = HSE_VALUE/1000000
  255. * PLL_N = 336
  256. * PLL_P = 2
  257. * PLL_Q = 7
  258. * VDD(V) = 3.3
  259. * Main regulator output voltage = Scale1 mode
  260. * Flash Latency(WS) = 5
  261. *
  262. * The system Clock is configured for L4 as follows:
  263. * System Clock source = PLL (MSI)
  264. * SYSCLK(Hz) = 80000000
  265. * HCLK(Hz) = 80000000
  266. * AHB Prescaler = 1
  267. * APB1 Prescaler = 1
  268. * APB2 Prescaler = 1
  269. * MSI Frequency(Hz) = MSI_VALUE (4000000)
  270. * LSE Frequency(Hz) = 32768
  271. * PLL_M = 1
  272. * PLL_N = 40
  273. * PLL_P = 7
  274. * PLL_Q = 2
  275. * PLL_R = 2 <= This is the source for SysClk, not as on F4/7 PLL_P
  276. * Flash Latency(WS) = 4
  277. * @param None
  278. * @retval None
  279. *
  280. * PLL is configured as follows:
  281. *
  282. * VCO_IN
  283. * F4/F7 = HSE / M
  284. * L4 = MSI / M
  285. * VCO_OUT
  286. * F4/F7 = HSE / M * N
  287. * L4 = MSI / M * N
  288. * PLLCLK
  289. * F4/F7 = HSE / M * N / P
  290. * L4 = MSI / M * N / R
  291. * PLL48CK
  292. * F4/F7 = HSE / M * N / Q
  293. * L4 = MSI / M * N / Q USB Clock is obtained over PLLSAI1
  294. *
  295. * SYSCLK = PLLCLK
  296. * HCLK = SYSCLK / AHB_PRESC
  297. * PCLKx = HCLK / APBx_PRESC
  298. *
  299. * Constraints on parameters:
  300. *
  301. * VCO_IN between 1MHz and 2MHz (2MHz recommended)
  302. * VCO_OUT between 192MHz and 432MHz
  303. * HSE = 8MHz
  304. * M = 2 .. 63 (inclusive)
  305. * N = 192 ... 432 (inclusive)
  306. * P = 2, 4, 6, 8
  307. * Q = 2 .. 15 (inclusive)
  308. *
  309. * AHB_PRESC=1,2,4,8,16,64,128,256,512
  310. * APBx_PRESC=1,2,4,8,16
  311. *
  312. * Output clocks:
  313. *
  314. * CPU SYSCLK max 168MHz
  315. * USB,RNG,SDIO PLL48CK must be 48MHz for USB
  316. * AHB HCLK max 168MHz
  317. * APB1 PCLK1 max 42MHz
  318. * APB2 PCLK2 max 84MHz
  319. *
  320. * Timers run from APBx if APBx_PRESC=1, else 2x APBx
  321. */
  322. void SystemClock_Config(void)
  323. {
  324. RCC_ClkInitTypeDef RCC_ClkInitStruct;
  325. RCC_OscInitTypeDef RCC_OscInitStruct;
  326. #if defined(STM32H7)
  327. RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
  328. #endif
  329. #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
  330. /* Enable Power Control clock */
  331. #if defined(STM32H7)
  332. MODIFY_REG(PWR->CR3, PWR_CR3_SCUEN, 0);
  333. #else
  334. __PWR_CLK_ENABLE();
  335. #endif
  336. /* The voltage scaling allows optimizing the power consumption when the device is
  337. clocked below the maximum system frequency, to update the voltage scaling value
  338. regarding system frequency refer to product datasheet. */
  339. __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  340. #elif defined(STM32L4)
  341. // Configure LSE Drive Capability
  342. __HAL_RCC_LSEDRIVE_CONFIG(RCC_LSEDRIVE_LOW);
  343. #endif
  344. #if defined(STM32H7)
  345. // Wait for PWR_FLAG_VOSRDY
  346. while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {
  347. }
  348. #endif
  349. /* Enable HSE Oscillator and activate PLL with HSE as source */
  350. #if defined(STM32F4) || defined(STM32F7) || defined(STM32H7)
  351. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  352. RCC_OscInitStruct.HSEState = MICROPY_HW_CLK_HSE_STATE;
  353. RCC_OscInitStruct.HSIState = RCC_HSI_OFF;
  354. #if defined(STM32H7)
  355. RCC_OscInitStruct.CSIState = RCC_CSI_OFF;
  356. #endif
  357. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  358. #elif defined(STM32L4)
  359. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_LSE|RCC_OSCILLATORTYPE_MSI;
  360. RCC_OscInitStruct.LSEState = RCC_LSE_ON;
  361. RCC_OscInitStruct.MSIState = RCC_MSI_ON;
  362. RCC_OscInitStruct.MSICalibrationValue = RCC_MSICALIBRATION_DEFAULT;
  363. RCC_OscInitStruct.MSIClockRange = RCC_MSIRANGE_6;
  364. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_MSI;
  365. #endif
  366. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  367. /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2
  368. clocks dividers */
  369. RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2);
  370. #if defined(STM32H7)
  371. RCC_ClkInitStruct.ClockType |= (RCC_CLOCKTYPE_D3PCLK1 | RCC_CLOCKTYPE_D1PCLK1);
  372. #endif
  373. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  374. #if defined(MICROPY_HW_CLK_LAST_FREQ) && MICROPY_HW_CLK_LAST_FREQ
  375. #if defined(STM32F7)
  376. #define FREQ_BKP BKP31R
  377. #elif defined(STM32L4)
  378. #error Unsupported Processor
  379. #else
  380. #define FREQ_BKP BKP19R
  381. #endif
  382. uint32_t m = RTC->FREQ_BKP;
  383. uint32_t n;
  384. uint32_t p;
  385. uint32_t q;
  386. // 222111HH HHQQQQPP nNNNNNNN NNMMMMMM
  387. uint32_t h = (m >> 22) & 0xf;
  388. uint32_t b1 = (m >> 26) & 0x7;
  389. uint32_t b2 = (m >> 29) & 0x7;
  390. q = (m >> 18) & 0xf;
  391. p = (((m >> 16) & 0x03)+1)*2;
  392. n = (m >> 6) & 0x3ff;
  393. m &= 0x3f;
  394. if ((q < 2) || (q > 15) || (p > 8) || (p < 2) || (n < 192) || (n >= 433) || (m < 2)) {
  395. m = MICROPY_HW_CLK_PLLM;
  396. n = MICROPY_HW_CLK_PLLN;
  397. p = MICROPY_HW_CLK_PLLP;
  398. q = MICROPY_HW_CLK_PLLQ;
  399. h = RCC_SYSCLK_DIV1;
  400. b1 = RCC_HCLK_DIV4;
  401. b2 = RCC_HCLK_DIV2;
  402. } else {
  403. h <<= 4;
  404. b1 <<= 10;
  405. b2 <<= 10;
  406. }
  407. RCC_OscInitStruct.PLL.PLLM = m; //MICROPY_HW_CLK_PLLM;
  408. RCC_OscInitStruct.PLL.PLLN = n; //MICROPY_HW_CLK_PLLN;
  409. RCC_OscInitStruct.PLL.PLLP = p; //MICROPY_HW_CLK_PLLP;
  410. RCC_OscInitStruct.PLL.PLLQ = q; //MICROPY_HW_CLK_PLLQ;
  411. RCC_ClkInitStruct.AHBCLKDivider = h; //RCC_SYSCLK_DIV1;
  412. RCC_ClkInitStruct.APB1CLKDivider = b1; //RCC_HCLK_DIV4;
  413. RCC_ClkInitStruct.APB2CLKDivider = b2; //RCC_HCLK_DIV2;
  414. #else // defined(MICROPY_HW_CLK_LAST_FREQ) && MICROPY_HW_CLK_LAST_FREQ
  415. RCC_OscInitStruct.PLL.PLLM = MICROPY_HW_CLK_PLLM;
  416. RCC_OscInitStruct.PLL.PLLN = MICROPY_HW_CLK_PLLN;
  417. RCC_OscInitStruct.PLL.PLLP = MICROPY_HW_CLK_PLLP;
  418. RCC_OscInitStruct.PLL.PLLQ = MICROPY_HW_CLK_PLLQ;
  419. #if defined(STM32L4) || defined(STM32H7)
  420. RCC_OscInitStruct.PLL.PLLR = MICROPY_HW_CLK_PLLR;
  421. #endif
  422. #if defined(STM32H7)
  423. RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_1;
  424. RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOWIDE;
  425. RCC_OscInitStruct.PLL.PLLFRACN = 0;
  426. #endif
  427. #if defined(STM32F4) || defined(STM32F7)
  428. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  429. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  430. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  431. #elif defined(STM32L4)
  432. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  433. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  434. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  435. #elif defined(STM32H7)
  436. RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1;
  437. RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2;
  438. RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV2;
  439. RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2;
  440. RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2;
  441. RCC_ClkInitStruct.APB4CLKDivider = RCC_APB4_DIV2;
  442. #endif
  443. #endif
  444. if(HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK) {
  445. __fatal_error("HAL_RCC_OscConfig");
  446. }
  447. #if defined(STM32H7)
  448. /* PLL3 for USB Clock */
  449. PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB;
  450. PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3;
  451. PeriphClkInitStruct.PLL3.PLL3M = 4;
  452. PeriphClkInitStruct.PLL3.PLL3N = 120;
  453. PeriphClkInitStruct.PLL3.PLL3P = 2;
  454. PeriphClkInitStruct.PLL3.PLL3Q = 5;
  455. PeriphClkInitStruct.PLL3.PLL3R = 2;
  456. PeriphClkInitStruct.PLL3.PLL3RGE = RCC_PLL3VCIRANGE_1;
  457. PeriphClkInitStruct.PLL3.PLL3VCOSEL = RCC_PLL3VCOWIDE;
  458. PeriphClkInitStruct.PLL3.PLL3FRACN = 0;
  459. if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK) {
  460. __fatal_error("HAL_RCCEx_PeriphCLKConfig");
  461. }
  462. #endif
  463. #if defined(STM32F7)
  464. /* Activate the OverDrive to reach the 200 MHz Frequency */
  465. if (HAL_PWREx_EnableOverDrive() != HAL_OK)
  466. {
  467. __fatal_error("HAL_PWREx_EnableOverDrive");
  468. }
  469. #endif
  470. #if !defined(MICROPY_HW_FLASH_LATENCY)
  471. #define MICROPY_HW_FLASH_LATENCY FLASH_LATENCY_5
  472. #endif
  473. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, MICROPY_HW_FLASH_LATENCY) != HAL_OK)
  474. {
  475. __fatal_error("HAL_RCC_ClockConfig");
  476. }
  477. #if defined(STM32H7)
  478. /* Activate CSI clock mandatory for I/O Compensation Cell*/
  479. __HAL_RCC_CSI_ENABLE() ;
  480. /* Enable SYSCFG clock mandatory for I/O Compensation Cell */
  481. __HAL_RCC_SYSCFG_CLK_ENABLE() ;
  482. /* Enable the I/O Compensation Cell */
  483. HAL_EnableCompensationCell();
  484. /* Enable the USB voltage level detector */
  485. HAL_PWREx_EnableUSBVoltageDetector();
  486. #endif
  487. #if defined(STM32F7)
  488. // The DFU bootloader changes the clocksource register from its default power
  489. // on reset value, so we set it back here, so the clocksources are the same
  490. // whether we were started from DFU or from a power on reset.
  491. RCC->DCKCFGR2 = 0;
  492. #endif
  493. #if defined(STM32L4)
  494. // Enable MSI-Hardware auto calibration mode with LSE
  495. HAL_RCCEx_EnableMSIPLLMode();
  496. RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
  497. PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_SAI1|RCC_PERIPHCLK_I2C1
  498. |RCC_PERIPHCLK_USB |RCC_PERIPHCLK_ADC
  499. |RCC_PERIPHCLK_RNG |RCC_PERIPHCLK_RTC;
  500. PeriphClkInitStruct.I2c1ClockSelection = RCC_I2C1CLKSOURCE_PCLK1;
  501. /* PLLSAI is used to clock USB, ADC, I2C1 and RNG. The frequency is
  502. MSI(4MHz)/PLLM(1)*PLLSAI1N(24)/PLLSAIQ(2) = 48MHz. See the STM32CubeMx
  503. application or the reference manual. */
  504. PeriphClkInitStruct.Sai1ClockSelection = RCC_SAI1CLKSOURCE_PLLSAI1;
  505. PeriphClkInitStruct.AdcClockSelection = RCC_ADCCLKSOURCE_PLLSAI1;
  506. PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLLSAI1;
  507. PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSE;
  508. PeriphClkInitStruct.RngClockSelection = RCC_RNGCLKSOURCE_PLLSAI1;
  509. PeriphClkInitStruct.PLLSAI1.PLLSAI1Source = RCC_PLLSOURCE_MSI;
  510. PeriphClkInitStruct.PLLSAI1.PLLSAI1M = 1;
  511. PeriphClkInitStruct.PLLSAI1.PLLSAI1N = 24;
  512. PeriphClkInitStruct.PLLSAI1.PLLSAI1P = RCC_PLLP_DIV7;
  513. PeriphClkInitStruct.PLLSAI1.PLLSAI1Q = RCC_PLLQ_DIV2;
  514. PeriphClkInitStruct.PLLSAI1.PLLSAI1R = RCC_PLLR_DIV2;
  515. PeriphClkInitStruct.PLLSAI1.PLLSAI1ClockOut = RCC_PLLSAI1_SAI1CLK
  516. |RCC_PLLSAI1_48M2CLK
  517. |RCC_PLLSAI1_ADC1CLK;
  518. if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  519. {
  520. __fatal_error("HAL_RCCEx_PeriphCLKConfig");
  521. }
  522. __PWR_CLK_ENABLE();
  523. HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1);
  524. HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq()/1000);
  525. HAL_SYSTICK_CLKSourceConfig(SYSTICK_CLKSOURCE_HCLK);
  526. NVIC_SetPriority(SysTick_IRQn, NVIC_EncodePriority(NVIC_PRIORITYGROUP_4, TICK_INT_PRIORITY, 0));
  527. #endif
  528. }