board.c 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322
  1. /***************************************************************************//**
  2. * @file board.c
  3. * @brief Board support of RT-Thread RTOS for EFM32
  4. * COPYRIGHT (C) 2011, RT-Thread Development Team
  5. * @author onelife
  6. * @version 0.4 beta
  7. *******************************************************************************
  8. * @section License
  9. * The license and distribution terms for this file may be found in the file
  10. * LICENSE in this distribution or at http://www.rt-thread.org/license/LICENSE
  11. *******************************************************************************
  12. * @section Change Logs
  13. * Date Author Notes
  14. * 2010-12-21 onelife Initial creation for EFM32
  15. * 2011-05-06 onelife Add EFM32 development kit and SPI Flash support
  16. * 2011-07-12 onelife Add SWO output enable function
  17. ******************************************************************************/
  18. /***************************************************************************//**
  19. * @addtogroup efm32
  20. * @{
  21. ******************************************************************************/
  22. /* Includes ------------------------------------------------------------------*/
  23. #include "board.h"
  24. /* Private typedef -----------------------------------------------------------*/
  25. /* Private define ------------------------------------------------------------*/
  26. #define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == RAM_MEM_BASE) || \
  27. ((VECTTAB) == FLASH_MEM_BASE))
  28. #define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF)
  29. /***************************************************************************//**
  30. * @addtogroup SysTick_clock_source
  31. * @{
  32. ******************************************************************************/
  33. #define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
  34. #define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
  35. #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
  36. ((SOURCE) == SysTick_CLKSource_HCLK_Div8))
  37. /***************************************************************************//**
  38. * @}
  39. ******************************************************************************/
  40. /* Private macro -------------------------------------------------------------*/
  41. /* Private variables ---------------------------------------------------------*/
  42. /* Private function prototypes -----------------------------------------------*/
  43. /* Private functions ---------------------------------------------------------*/
  44. /***************************************************************************//**
  45. * @brief
  46. * Set the allocation and offset of the vector table
  47. *
  48. * @details
  49. *
  50. * @note
  51. *
  52. * @param[in] NVIC_VectTab
  53. * Indicate the vector table is allocated in RAM or ROM
  54. *
  55. * @param[in] Offset
  56. * The vector table offset
  57. ******************************************************************************/
  58. static void NVIC_SetVectorTable(
  59. rt_uint32_t NVIC_VectTab,
  60. rt_uint32_t Offset)
  61. {
  62. /* Check the parameters */
  63. RT_ASSERT(IS_NVIC_VECTTAB(NVIC_VectTab));
  64. RT_ASSERT(IS_NVIC_OFFSET(Offset));
  65. SCB->VTOR = NVIC_VectTab | (Offset & (rt_uint32_t)0x1FFFFF80);
  66. }
  67. /***************************************************************************//**
  68. * @brief
  69. * Configure the address of vector table
  70. *
  71. * @details
  72. *
  73. * @note
  74. *
  75. ******************************************************************************/
  76. static void NVIC_Configuration(void)
  77. {
  78. #ifdef VECT_TAB_RAM
  79. /* Set the vector table allocated at 0x20000000 */
  80. NVIC_SetVectorTable(RAM_MEM_BASE, 0x0);
  81. #else /* VECT_TAB_FLASH */
  82. /* Set the vector table allocated at 0x00000000 */
  83. NVIC_SetVectorTable(FLASH_MEM_BASE, 0x0);
  84. #endif
  85. /* Set NVIC Preemption Priority Bits: 0 bit for pre-emption, 4 bits for
  86. subpriority */
  87. NVIC_SetPriorityGrouping(0x7UL);
  88. /* Set Base Priority Mask Register */
  89. __set_BASEPRI(EFM32_BASE_PRI_DEFAULT);
  90. }
  91. /***************************************************************************//**
  92. * @brief
  93. * Enable high frequency crystal oscillator (HFXO), and set HFCLK domain to
  94. * use HFXO as source.
  95. *
  96. * @details
  97. *
  98. * @note
  99. *
  100. ******************************************************************************/
  101. static void switchToHFXO(void)
  102. {
  103. CMU_TypeDef *cmu = CMU;
  104. /* Turning on HFXO to increase frequency accuracy. */
  105. /* Waiting until oscillator is stable */
  106. cmu->OSCENCMD = CMU_OSCENCMD_HFXOEN;
  107. while (!(cmu->STATUS && CMU_STATUS_HFXORDY)) ;
  108. /* Switching the CPU clock source to HFXO */
  109. cmu->CMD = CMU_CMD_HFCLKSEL_HFXO;
  110. /* Turning off the high frequency RC Oscillator (HFRCO) */
  111. /* GENERATL WARNING! Make sure not to disable the current
  112. * source of the HFCLK. */
  113. cmu->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
  114. }
  115. /***************************************************************************//**
  116. * @brief
  117. * Configure the SysTick clock source
  118. *
  119. * @details
  120. *
  121. * @note
  122. *
  123. * @param[in] SysTick_CLKSource
  124. * Specifies the SysTick clock source.
  125. *
  126. * @arg SysTick_CLKSource_HCLK_Div8
  127. * AHB clock divided by 8 selected as SysTick clock source.
  128. *
  129. * @arg SysTick_CLKSource_HCLK
  130. * AHB clock selected as SysTick clock source.
  131. ******************************************************************************/
  132. static void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
  133. {
  134. /* Check the parameters */
  135. RT_ASSERT(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
  136. if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
  137. {
  138. SysTick->CTRL |= SysTick_CLKSource_HCLK;
  139. }
  140. else
  141. {
  142. SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
  143. }
  144. }
  145. /***************************************************************************//**
  146. * @brief
  147. * Configure the SysTick for OS tick.
  148. *
  149. * @details
  150. *
  151. * @note
  152. *
  153. ******************************************************************************/
  154. static void SysTick_Configuration(void)
  155. {
  156. rt_uint32_t core_clock;
  157. rt_uint32_t cnts;
  158. switchToHFXO();
  159. core_clock = SystemCoreClockGet();
  160. cnts = core_clock / RT_TICK_PER_SECOND;
  161. SysTick_Config(cnts);
  162. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
  163. }
  164. /***************************************************************************//**
  165. * @brief
  166. * Enable SWO.
  167. *
  168. * @details
  169. *
  170. * @note
  171. *
  172. ******************************************************************************/
  173. void setupSWO(void)
  174. {
  175. rt_uint32_t *dwt_ctrl = (rt_uint32_t *) 0xE0001000;
  176. rt_uint32_t *tpiu_prescaler = (rt_uint32_t *) 0xE0040010;
  177. rt_uint32_t *tpiu_protocol = (rt_uint32_t *) 0xE00400F0;
  178. CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
  179. /* Enable Serial wire output pin */
  180. GPIO->ROUTE |= GPIO_ROUTE_SWOPEN;
  181. /* Set location 1 */
  182. GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC1;
  183. /* Enable output on pin */
  184. GPIO->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE15_MASK);
  185. GPIO->P[2].MODEH |= GPIO_P_MODEH_MODE15_PUSHPULL;
  186. /* Enable debug clock AUXHFRCO */
  187. CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
  188. while(!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));
  189. /* Enable trace in core debug */
  190. CoreDebug->DHCSR |= 1;
  191. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  192. /* Enable PC and IRQ sampling output */
  193. *dwt_ctrl = 0x400113FF;
  194. /* Set TPIU prescaler to 16. */
  195. *tpiu_prescaler = 0xf;
  196. /* Set protocol to NRZ */
  197. *tpiu_protocol = 2;
  198. /* Unlock ITM and output data */
  199. ITM->LAR = 0xC5ACCE55;
  200. ITM->TCR = 0x10009;
  201. }
  202. /***************************************************************************//**
  203. * @brief
  204. * Initialize the board.
  205. *
  206. * @details
  207. *
  208. * @note
  209. *
  210. ******************************************************************************/
  211. void rt_hw_board_init(void)
  212. {
  213. /* Chip errata */
  214. CHIP_Init();
  215. #if defined(EFM32_G290_DK)
  216. /* Initialize DVK board register access */
  217. DVK_init();
  218. #endif
  219. /* NVIC Configuration */
  220. NVIC_Configuration();
  221. /* Configure external oscillator */
  222. SystemHFXOClockSet(EFM32_HFXO_FREQUENCY);
  223. /* Configure the SysTick */
  224. SysTick_Configuration();
  225. }
  226. /***************************************************************************//**
  227. * @brief
  228. * Initialize the hardware drivers.
  229. *
  230. * @details
  231. *
  232. * @note
  233. *
  234. ******************************************************************************/
  235. void rt_hw_driver_init(void)
  236. {
  237. CMU_ClockEnable(cmuClock_HFPER, true);
  238. /* Enable GPIO */
  239. CMU_ClockEnable(cmuClock_GPIO, true);
  240. /* Enabling clock to the interface of the low energy modules */
  241. CMU_ClockEnable(cmuClock_CORELE, true);
  242. #ifdef EFM32_SWO_ENABLE
  243. /* Enable SWO */
  244. setupSWO();
  245. #endif
  246. /* Initialize DMA */
  247. rt_hw_dma_init();
  248. /* Initialize USART */
  249. #if defined(EFM32_G290_DK)
  250. DVK_enablePeripheral(DVK_RS232A);
  251. DVK_enablePeripheral(DVK_SPI);
  252. #endif
  253. #if (defined(RT_USING_USART0) || defined(RT_USING_USART1) || defined(RT_USING_USART2))
  254. rt_hw_usart_init();
  255. #endif
  256. /* Setup console */
  257. rt_console_set_device(CONSOLE_DEVICE);
  258. /* Initialize Timer */
  259. #if (defined(RT_USING_TIMER0) || defined(RT_USING_TIMER1) || defined(RT_USING_TIMER2))
  260. rt_hw_timer_init();
  261. #endif
  262. /* Initialize ADC */
  263. #if defined(RT_USING_ADC0)
  264. rt_hw_adc_init();
  265. #endif
  266. /* Initialize ACMP */
  267. #if (defined(RT_USING_ACMP0) || defined(RT_USING_ACMP1))
  268. rt_hw_acmp_init();
  269. #endif
  270. /* Initialize IIC */
  271. #if (defined(RT_USING_IIC0) || defined(RT_USING_IIC1))
  272. rt_hw_iic_init();
  273. #endif
  274. /* Initialize RTC */
  275. #if defined(RT_USING_RTC)
  276. rt_hw_rtc_init();
  277. #endif
  278. }
  279. /***************************************************************************//**
  280. * @}
  281. ******************************************************************************/