board.c 8.5 KB

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