board.c 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  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. * 2011-12-08 onelife Add giant gecko development kit support
  18. * 2011-12-09 onelife Add giant gecko support
  19. * 2011-12-09 onelife Add LEUART module support
  20. * 2011-12-14 onelife Add LFXO enabling routine in driver initialization
  21. * function
  22. * 2011-12-15 onelife Add MicroSD enabling routine in driver
  23. * initialization function
  24. ******************************************************************************/
  25. /***************************************************************************//**
  26. * @addtogroup efm32
  27. * @{
  28. ******************************************************************************/
  29. /* Includes ------------------------------------------------------------------*/
  30. #include "board.h"
  31. /* Private typedef -----------------------------------------------------------*/
  32. /* Private define ------------------------------------------------------------*/
  33. #define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == RAM_MEM_BASE) || \
  34. ((VECTTAB) == FLASH_MEM_BASE))
  35. #define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF)
  36. /***************************************************************************//**
  37. * @addtogroup SysTick_clock_source
  38. * @{
  39. ******************************************************************************/
  40. #define SysTick_CLKSource_HCLK_Div8 ((uint32_t)0xFFFFFFFB)
  41. #define SysTick_CLKSource_HCLK ((uint32_t)0x00000004)
  42. #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_HCLK) || \
  43. ((SOURCE) == SysTick_CLKSource_HCLK_Div8))
  44. /***************************************************************************//**
  45. * @}
  46. ******************************************************************************/
  47. /* Private macro -------------------------------------------------------------*/
  48. /* Private variables ---------------------------------------------------------*/
  49. /* Private function prototypes -----------------------------------------------*/
  50. /* Private functions ---------------------------------------------------------*/
  51. /***************************************************************************//**
  52. * @brief
  53. * Set the allocation and offset of the vector table
  54. *
  55. * @details
  56. *
  57. * @note
  58. *
  59. * @param[in] NVIC_VectTab
  60. * Indicate the vector table is allocated in RAM or ROM
  61. *
  62. * @param[in] Offset
  63. * The vector table offset
  64. ******************************************************************************/
  65. static void NVIC_SetVectorTable(
  66. rt_uint32_t NVIC_VectTab,
  67. rt_uint32_t Offset)
  68. {
  69. /* Check the parameters */
  70. RT_ASSERT(IS_NVIC_VECTTAB(NVIC_VectTab));
  71. RT_ASSERT(IS_NVIC_OFFSET(Offset));
  72. SCB->VTOR = NVIC_VectTab | (Offset & (rt_uint32_t)0x1FFFFF80);
  73. }
  74. /***************************************************************************//**
  75. * @brief
  76. * Configure the address of vector table
  77. *
  78. * @details
  79. *
  80. * @note
  81. *
  82. ******************************************************************************/
  83. static void NVIC_Configuration(void)
  84. {
  85. #ifdef VECT_TAB_RAM
  86. /* Set the vector table allocated at 0x20000000 */
  87. NVIC_SetVectorTable(RAM_MEM_BASE, 0x0);
  88. #else /* VECT_TAB_FLASH */
  89. /* Set the vector table allocated at 0x00000000 */
  90. NVIC_SetVectorTable(FLASH_MEM_BASE, 0x0);
  91. #endif
  92. /* Set NVIC Preemption Priority Bits: 0 bit for pre-emption, 4 bits for
  93. subpriority */
  94. NVIC_SetPriorityGrouping(0x7UL);
  95. /* Set Base Priority Mask Register */
  96. __set_BASEPRI(EFM32_BASE_PRI_DEFAULT);
  97. }
  98. /***************************************************************************//**
  99. * @brief
  100. * Enable high frequency crystal oscillator (HFXO), and set HFCLK domain to
  101. * use HFXO as source.
  102. *
  103. * @details
  104. *
  105. * @note
  106. *
  107. ******************************************************************************/
  108. static void efm_hfxo_switch(void)
  109. {
  110. CMU_TypeDef *cmu = CMU;
  111. /* Turning on HFXO to increase frequency accuracy. */
  112. /* Waiting until oscillator is stable */
  113. cmu->OSCENCMD = CMU_OSCENCMD_HFXOEN;
  114. while (!(cmu->STATUS && CMU_STATUS_HFXORDY)) ;
  115. /* Switching the CPU clock source to HFXO */
  116. cmu->CMD = CMU_CMD_HFCLKSEL_HFXO;
  117. /* Turning off the high frequency RC Oscillator (HFRCO) */
  118. /* GENERATL WARNING! Make sure not to disable the current
  119. * source of the HFCLK. */
  120. cmu->OSCENCMD = CMU_OSCENCMD_HFRCODIS;
  121. }
  122. /***************************************************************************//**
  123. * @brief
  124. * Configure the SysTick clock source
  125. *
  126. * @details
  127. *
  128. * @note
  129. *
  130. * @param[in] SysTick_CLKSource
  131. * Specifies the SysTick clock source.
  132. *
  133. * @arg SysTick_CLKSource_HCLK_Div8
  134. * AHB clock divided by 8 selected as SysTick clock source.
  135. *
  136. * @arg SysTick_CLKSource_HCLK
  137. * AHB clock selected as SysTick clock source.
  138. ******************************************************************************/
  139. static void SysTick_CLKSourceConfig(uint32_t SysTick_CLKSource)
  140. {
  141. /* Check the parameters */
  142. RT_ASSERT(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
  143. if (SysTick_CLKSource == SysTick_CLKSource_HCLK)
  144. {
  145. SysTick->CTRL |= SysTick_CLKSource_HCLK;
  146. }
  147. else
  148. {
  149. SysTick->CTRL &= SysTick_CLKSource_HCLK_Div8;
  150. }
  151. }
  152. /***************************************************************************//**
  153. * @brief
  154. * Configure the SysTick for OS tick.
  155. *
  156. * @details
  157. *
  158. * @note
  159. *
  160. ******************************************************************************/
  161. static void SysTick_Configuration(void)
  162. {
  163. rt_uint32_t core_clock;
  164. rt_uint32_t cnts;
  165. efm_hfxo_switch();
  166. core_clock = SystemCoreClockGet();
  167. cnts = core_clock / RT_TICK_PER_SECOND;
  168. SysTick_Config(cnts);
  169. SysTick_CLKSourceConfig(SysTick_CLKSource_HCLK);
  170. }
  171. /***************************************************************************//**
  172. * @brief
  173. * Enable SWO.
  174. *
  175. * @details
  176. *
  177. * @note
  178. *
  179. ******************************************************************************/
  180. void efm_swo_setup(void)
  181. {
  182. rt_uint32_t *dwt_ctrl = (rt_uint32_t *) 0xE0001000;
  183. rt_uint32_t *tpiu_prescaler = (rt_uint32_t *) 0xE0040010;
  184. rt_uint32_t *tpiu_protocol = (rt_uint32_t *) 0xE00400F0;
  185. CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
  186. /* Enable Serial wire output pin */
  187. GPIO->ROUTE |= GPIO_ROUTE_SWOPEN;
  188. /* Set location 1 */
  189. GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC1;
  190. /* Enable output on pin */
  191. GPIO->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE15_MASK);
  192. GPIO->P[2].MODEH |= GPIO_P_MODEH_MODE15_PUSHPULL;
  193. /* Enable debug clock AUXHFRCO */
  194. CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
  195. while(!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));
  196. /* Enable trace in core debug */
  197. CoreDebug->DHCSR |= 1;
  198. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  199. /* Enable PC and IRQ sampling output */
  200. *dwt_ctrl = 0x400113FF;
  201. /* Set TPIU prescaler to 16. */
  202. *tpiu_prescaler = 0xf;
  203. /* Set protocol to NRZ */
  204. *tpiu_protocol = 2;
  205. /* Unlock ITM and output data */
  206. ITM->LAR = 0xC5ACCE55;
  207. ITM->TCR = 0x10009;
  208. }
  209. /***************************************************************************//**
  210. * @brief
  211. * Initialize the board.
  212. *
  213. * @details
  214. *
  215. * @note
  216. *
  217. ******************************************************************************/
  218. void rt_hw_board_init(void)
  219. {
  220. /* Chip errata */
  221. CHIP_Init();
  222. /* Initialize DVK board register access */
  223. #if defined(EFM32_GXXX_DK)
  224. DVK_init();
  225. #elif defined(EFM32GG_DK3750)
  226. DVK_init(DVK_Init_EBI);
  227. #endif
  228. /* NVIC Configuration */
  229. NVIC_Configuration();
  230. /* Configure external oscillator */
  231. SystemHFXOClockSet(EFM32_HFXO_FREQUENCY);
  232. /* Configure the SysTick */
  233. SysTick_Configuration();
  234. }
  235. /***************************************************************************//**
  236. * @brief
  237. * Initialize the hardware drivers.
  238. *
  239. * @details
  240. *
  241. * @note
  242. *
  243. ******************************************************************************/
  244. void rt_hw_driver_init(void)
  245. {
  246. CMU_ClockEnable(cmuClock_HFPER, true);
  247. /* Enable GPIO */
  248. CMU_ClockEnable(cmuClock_GPIO, true);
  249. /* Enabling clock to the interface of the low energy modules */
  250. CMU_ClockEnable(cmuClock_CORELE, true);
  251. /* Starting LFXO and waiting until it is stable */
  252. #if defined(EFM32_USING_LFXO)
  253. CMU_OscillatorEnable(cmuOsc_LFXO, true, true);
  254. /* Select LFXO for specified module (and wait for it to stabilize) */
  255. #if (defined(RT_USING_LEUART0) || defined(RT_USING_LEUART1))
  256. CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
  257. #endif
  258. #if defined(RT_USING_RTC)
  259. CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO);
  260. #endif
  261. #endif
  262. /* Enable SWO */
  263. #if defined(EFM32_SWO_ENABLE)
  264. efm_swo_setup();
  265. #endif
  266. /* Initialize DMA */
  267. rt_hw_dma_init();
  268. /* Initialize USART */
  269. #if (defined(RT_USING_USART0) || defined(RT_USING_USART1) || \
  270. defined(RT_USING_USART2) || defined(RT_USING_UART0) || \
  271. defined(RT_USING_UART1))
  272. rt_hw_usart_init();
  273. #endif
  274. /* Initialize LEUART */
  275. #if (defined(RT_USING_LEUART0) || defined(RT_USING_LEUART1))
  276. rt_hw_leuart_init();
  277. #endif
  278. /* Setup Console */
  279. #if defined(EFM32_GXXX_DK)
  280. DVK_enablePeripheral(DVK_RS232A);
  281. DVK_enablePeripheral(DVK_SPI);
  282. #elif defined(EFM32GG_DK3750)
  283. #if (RT_CONSOLE_DEVICE == EFM_UART1)
  284. DVK_enablePeripheral(DVK_RS232_UART);
  285. #elif (RT_CONSOLE_DEVICE == EFM_LEUART1)
  286. DVK_enablePeripheral(DVK_RS232_LEUART);
  287. #endif
  288. #endif
  289. rt_console_set_device(CONSOLE_DEVICE);
  290. /* Initialize Timer */
  291. #if (defined(RT_USING_TIMER0) || defined(RT_USING_TIMER1) || defined(RT_USING_TIMER2))
  292. rt_hw_timer_init();
  293. #endif
  294. /* Initialize ADC */
  295. #if defined(RT_USING_ADC0)
  296. rt_hw_adc_init();
  297. #endif
  298. /* Initialize ACMP */
  299. #if (defined(RT_USING_ACMP0) || defined(RT_USING_ACMP1))
  300. rt_hw_acmp_init();
  301. #endif
  302. /* Initialize IIC */
  303. #if (defined(RT_USING_IIC0) || defined(RT_USING_IIC1))
  304. rt_hw_iic_init();
  305. #endif
  306. /* Initialize RTC */
  307. #if defined(RT_USING_RTC)
  308. rt_hw_rtc_init();
  309. #endif
  310. /* Enable SPI access to MicroSD card */
  311. #if defined(EFM32_USING_SPISD)
  312. #if defined(EFM32_GXXX_DK)
  313. DVK_writeRegister(BC_SPI_CFG, 1);
  314. #elif defined(EFM32GG_DK3750)
  315. DVK_enablePeripheral(DVK_MICROSD);
  316. #endif
  317. #endif
  318. /* Enable SPI access to Ethernet */
  319. #if defined(EFM32_USING_ETHERNET)
  320. DVK_enablePeripheral(DVK_ETH);
  321. #endif
  322. }
  323. /***************************************************************************//**
  324. * @}
  325. ******************************************************************************/