board.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2009-09-22 Bernard add board.h to this bsp
  9. * 2017-12-29 ZYH Correctly generate the 48M clock
  10. */
  11. #include <rtthread.h>
  12. #include "board.h"
  13. /**
  14. * @addtogroup STM32
  15. */
  16. /*@{*/
  17. #if defined(RCC_PERIPHCLK_SDIO) || defined(RCC_PERIPHCLK_CEC) || defined(RCC_PERIPHCLK_LTDC)\
  18. || defined(RCC_PERIPHCLK_SPDIFRX) || defined(RCC_PERIPHCLK_FMPI2C1) || defined(RCC_PERIPHCLK_LPTIM1)
  19. #warning Please give priority to the correctness of the clock tree when the peripherals are abnormal
  20. #endif
  21. static void SystemClock_Config(void)
  22. {
  23. rt_uint32_t source_clk, sys_clk;
  24. #if !defined(RT_USING_HSI) && (RT_HSE_VALVE % 1000000 != 0)
  25. #error HSE must be integer of MHz
  26. #endif
  27. #ifdef RT_USING_HSI
  28. #define CLOCK_SOURE_VALUE HSI_VALUE
  29. #else
  30. #define CLOCK_SOURE_VALUE HSE_VALUE
  31. #endif
  32. source_clk = CLOCK_SOURE_VALUE / 1000000UL;
  33. sys_clk = HCLK_VALUE / 1000000UL;
  34. RCC_OscInitTypeDef RCC_OscInitStruct;
  35. RCC_ClkInitTypeDef RCC_ClkInitStruct;
  36. #if defined(RT_USING_RTC) || defined(RCC_PERIPHCLK_CLK48)
  37. RCC_PeriphCLKInitTypeDef PeriphClkInitStruct;
  38. #endif
  39. /**Configure the main internal regulator output voltage
  40. */
  41. __HAL_RCC_PWR_CLK_ENABLE();
  42. __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1);
  43. /**Initializes the CPU, AHB and APB busses clocks
  44. */
  45. #ifdef RT_USING_HSI
  46. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI;
  47. #else
  48. RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  49. #endif
  50. #ifdef RT_USING_RTC
  51. RCC_OscInitStruct.OscillatorType |= RCC_OSCILLATORTYPE_LSI;
  52. RCC_OscInitStruct.LSIState = RCC_LSI_ON;
  53. #endif
  54. #ifdef RT_USING_HSI
  55. RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  56. RCC_OscInitStruct.HSICalibrationValue = source_clk;
  57. #else
  58. #ifdef BSP_HSE_BY_PASS
  59. RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS;
  60. #else
  61. RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  62. #endif
  63. #endif
  64. RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  65. #ifdef RT_USING_HSI
  66. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI;
  67. #else
  68. RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  69. #endif
  70. if (source_clk % 2 == 0)
  71. {
  72. RCC_OscInitStruct.PLL.PLLM = source_clk / 2; //Get 2M clock
  73. if ((sys_clk * 4) % 48 == 0)
  74. {
  75. RCC_OscInitStruct.PLL.PLLN = sys_clk * 2;//Get 4*HCLK_VALUE
  76. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;//Get HCLK_VALUE
  77. }
  78. else if ((sys_clk * 6) % 48 == 0)
  79. {
  80. RCC_OscInitStruct.PLL.PLLN = sys_clk * 3;//Get 6*HCLK_VALUE
  81. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV6;//Get HCLK_VALUE
  82. }
  83. else if ((sys_clk * 8) % 48 == 0)
  84. {
  85. RCC_OscInitStruct.PLL.PLLN = sys_clk * 4;//Get 8*HCLK_VALUE
  86. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV8;//Get HCLK_VALUE
  87. }
  88. else
  89. {
  90. //can not get 48M Clock USB is unuseable
  91. RCC_OscInitStruct.PLL.PLLN = sys_clk;//Get 2*HCLK_VALUE
  92. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;//Get HCLK_VALUE
  93. }
  94. }
  95. else
  96. {
  97. RCC_OscInitStruct.PLL.PLLM = source_clk;//Get 1M clock
  98. if ((sys_clk * 4) % 48 == 0)
  99. {
  100. RCC_OscInitStruct.PLL.PLLN = sys_clk * 4;//Get 4*HCLK_VALUE
  101. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV4;//Get HCLK_VALUE
  102. }
  103. else if ((sys_clk * 6) % 48 == 0)
  104. {
  105. RCC_OscInitStruct.PLL.PLLN = sys_clk * 6;//Get 6*HCLK_VALUE
  106. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV6;//Get HCLK_VALUE
  107. }
  108. else if ((sys_clk * 8) % 48 == 0)
  109. {
  110. RCC_OscInitStruct.PLL.PLLN = sys_clk * 8;//Get 8*HCLK_VALUE
  111. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV8;//Get HCLK_VALUE
  112. }
  113. else
  114. {
  115. //can not get 48M Clock USB is unuseable
  116. RCC_OscInitStruct.PLL.PLLN = sys_clk * 2;//Get 2*HCLK_VALUE
  117. RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2;//Get HCLK_VALUE
  118. }
  119. }
  120. RCC_OscInitStruct.PLL.PLLQ = source_clk / RCC_OscInitStruct.PLL.PLLM * RCC_OscInitStruct.PLL.PLLN / 48; //Get 48M Clock
  121. if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  122. {
  123. while (1)
  124. {}
  125. }
  126. /**Initializes the CPU, AHB and APB busses clocks
  127. */
  128. RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK
  129. | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2;
  130. RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  131. RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  132. #if (RT_HSE_HCLK <= 42000000UL)
  133. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1;
  134. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  135. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_1) != HAL_OK)
  136. {
  137. while (1)
  138. {}
  139. }
  140. #elif (RT_HSE_HCLK <= 84000000UL)
  141. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  142. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  143. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  144. {
  145. while (1)
  146. {}
  147. }
  148. #elif (RT_HSE_HCLK <= 100000000UL)
  149. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  150. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;
  151. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_3) != HAL_OK)
  152. {
  153. while (1)
  154. {}
  155. }
  156. #elif (RT_HSE_HCLK <= 168000000UL)
  157. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4;
  158. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2;
  159. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5) != HAL_OK)
  160. {
  161. while (1)
  162. {}
  163. }
  164. #else
  165. RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV8;
  166. RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV4;
  167. if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_7) != HAL_OK)
  168. {
  169. while (1)
  170. {}
  171. }
  172. #endif
  173. #if defined(RT_USING_RTC) || defined(RCC_PERIPHCLK_CLK48)
  174. PeriphClkInitStruct.PeriphClockSelection = 0;
  175. #ifdef RT_USING_RTC
  176. PeriphClkInitStruct.PeriphClockSelection |= RCC_PERIPHCLK_RTC;
  177. PeriphClkInitStruct.RTCClockSelection = RCC_RTCCLKSOURCE_LSI;
  178. #endif
  179. #ifdef RCC_PERIPHCLK_CLK48
  180. PeriphClkInitStruct.PeriphClockSelection |= RCC_PERIPHCLK_CLK48;
  181. PeriphClkInitStruct.Clk48ClockSelection = RCC_CLK48CLKSOURCE_PLLQ;
  182. #endif
  183. if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct) != HAL_OK)
  184. {
  185. while (1)
  186. {}
  187. }
  188. #endif
  189. }
  190. /**
  191. * This is the timer interrupt service routine.
  192. *
  193. */
  194. void SysTick_Handler(void)
  195. {
  196. /* enter interrupt */
  197. rt_interrupt_enter();
  198. /* tick for HAL Library */
  199. HAL_IncTick();
  200. rt_tick_increase();
  201. /* leave interrupt */
  202. rt_interrupt_leave();
  203. }
  204. /* re-implementat tick interface for STM32 HAL */
  205. HAL_StatusTypeDef HAL_InitTick(uint32_t TickPriority)
  206. {
  207. /*Configure the SysTick to have interrupt in 1ms time basis*/
  208. HAL_SYSTICK_Config(HAL_RCC_GetHCLKFreq() / RT_TICK_PER_SECOND);
  209. /*Configure the SysTick IRQ priority */
  210. HAL_NVIC_SetPriority(SysTick_IRQn, TickPriority, 0);
  211. /* Return function status */
  212. return HAL_OK;
  213. }
  214. void HAL_Delay(__IO uint32_t Delay)
  215. {
  216. rt_thread_delay(Delay);
  217. }
  218. void HAL_SuspendTick(void)
  219. {
  220. /* we should not suspend tick */
  221. }
  222. void HAL_ResumeTick(void)
  223. {
  224. /* we should not resume tick */
  225. }
  226. void HAL_MspInit(void)
  227. {
  228. HAL_NVIC_SetPriorityGrouping(NVIC_PRIORITYGROUP_4);
  229. /* System interrupt init*/
  230. /* MemoryManagement_IRQn interrupt configuration */
  231. HAL_NVIC_SetPriority(MemoryManagement_IRQn, 0, 0);
  232. /* BusFault_IRQn interrupt configuration */
  233. HAL_NVIC_SetPriority(BusFault_IRQn, 0, 0);
  234. /* UsageFault_IRQn interrupt configuration */
  235. HAL_NVIC_SetPriority(UsageFault_IRQn, 0, 0);
  236. /* SVCall_IRQn interrupt configuration */
  237. HAL_NVIC_SetPriority(SVCall_IRQn, 0, 0);
  238. /* DebugMonitor_IRQn interrupt configuration */
  239. HAL_NVIC_SetPriority(DebugMonitor_IRQn, 0, 0);
  240. /* PendSV_IRQn interrupt configuration */
  241. HAL_NVIC_SetPriority(PendSV_IRQn, 15, 0);
  242. /* SysTick_IRQn interrupt configuration */
  243. HAL_NVIC_SetPriority(SysTick_IRQn, 15, 0);
  244. }
  245. /**
  246. * This function will initial STM32 board.
  247. */
  248. void rt_hw_board_init()
  249. {
  250. /* Configure the system clock @ 84 Mhz */
  251. SystemClock_Config();
  252. HAL_Init();
  253. #ifdef RT_USING_HEAP
  254. rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
  255. #endif
  256. #ifdef RT_USING_COMPONENTS_INIT
  257. rt_components_board_init();
  258. #endif
  259. #ifdef RT_USING_CONSOLE
  260. rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
  261. #endif
  262. }