1
0

board.c 7.9 KB

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