1
0

board.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416
  1. /***************************************************************************//**
  2. * @file board.c
  3. * @brief Board support of RT-Thread RTOS for EFM32
  4. * COPYRIGHT (C) 2012, RT-Thread Development Team
  5. * @author onelife
  6. * @version 1.0
  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 initialization routine in driver
  23. * initialization function
  24. * 2011-12-29 onelife Add keys and joystick initialization routine in
  25. * driver initialization function
  26. * 2012-02-15 onelife Modify SWO setup function to support giant gecko
  27. * 2012-xx-xx onelife Modify system clock and ticket related code
  28. ******************************************************************************/
  29. /***************************************************************************//**
  30. * @addtogroup efm32
  31. * @{
  32. ******************************************************************************/
  33. /* Includes ------------------------------------------------------------------*/
  34. #include "board.h"
  35. /* Private typedef -----------------------------------------------------------*/
  36. /* Private define ------------------------------------------------------------*/
  37. #define IS_NVIC_VECTTAB(VECTTAB) (((VECTTAB) == RAM_MEM_BASE) || \
  38. ((VECTTAB) == FLASH_MEM_BASE))
  39. #define IS_NVIC_OFFSET(OFFSET) ((OFFSET) < 0x000FFFFF)
  40. /***************************************************************************//**
  41. * @addtogroup SysTick_clock_source
  42. * @{
  43. ******************************************************************************/
  44. #define SysTick_CLKSource_MASK ((rt_uint32_t)0x00000004)
  45. #define SysTick_CLKSource_RTC ((rt_uint32_t)0x00000000)
  46. #define SysTick_CLKSource_HFCORECLK ((rt_uint32_t)0x00000004)
  47. #define IS_SYSTICK_CLK_SOURCE(SOURCE) (((SOURCE) == SysTick_CLKSource_RTC) || \
  48. ((SOURCE) == SysTick_CLKSource_HFCORECLK))
  49. /***************************************************************************//**
  50. * @}
  51. ******************************************************************************/
  52. /* Private macro -------------------------------------------------------------*/
  53. /* Private variables ---------------------------------------------------------*/
  54. /* Private function prototypes -----------------------------------------------*/
  55. /* Private functions ---------------------------------------------------------*/
  56. /***************************************************************************//**
  57. * @brief
  58. * Set the allocation and offset of the vector table
  59. *
  60. * @details
  61. *
  62. * @note
  63. *
  64. * @param[in] NVIC_VectTab
  65. * Indicate the vector table is allocated in RAM or ROM
  66. *
  67. * @param[in] Offset
  68. * The vector table offset
  69. ******************************************************************************/
  70. static void NVIC_SetVectorTable(
  71. rt_uint32_t NVIC_VectTab,
  72. rt_uint32_t Offset)
  73. {
  74. /* Check the parameters */
  75. RT_ASSERT(IS_NVIC_VECTTAB(NVIC_VectTab));
  76. RT_ASSERT(IS_NVIC_OFFSET(Offset));
  77. SCB->VTOR = NVIC_VectTab | (Offset & (rt_uint32_t)0x1FFFFF80);
  78. }
  79. /***************************************************************************//**
  80. * @brief
  81. * Configure the address of vector table
  82. *
  83. * @details
  84. *
  85. * @note
  86. *
  87. ******************************************************************************/
  88. static void NVIC_Configuration(void)
  89. {
  90. #ifdef VECT_TAB_RAM
  91. /* Set the vector table allocated at 0x20000000 */
  92. NVIC_SetVectorTable(RAM_MEM_BASE, 0x0);
  93. #else /* VECT_TAB_FLASH */
  94. /* Set the vector table allocated at 0x00000000 */
  95. NVIC_SetVectorTable(FLASH_MEM_BASE, 0x0);
  96. #endif
  97. /* Set NVIC Preemption Priority Bits: 0 bit for pre-emption, 4 bits for
  98. subpriority */
  99. NVIC_SetPriorityGrouping(0x7UL);
  100. /* Set Base Priority Mask Register */
  101. __set_BASEPRI(EFM32_BASE_PRI_DEFAULT);
  102. }
  103. /***************************************************************************//**
  104. * @brief
  105. * Configure the SysTick clock source
  106. *
  107. * @details
  108. *
  109. * @note
  110. *
  111. * @param[in] SysTick_CLKSource
  112. * Specifies the SysTick clock source.
  113. *
  114. * @arg SysTick_CLKSource_HCLK_Div8
  115. * AHB clock divided by 8 selected as SysTick clock source.
  116. *
  117. * @arg SysTick_CLKSource_HCLK
  118. * AHB clock selected as SysTick clock source.
  119. ******************************************************************************/
  120. static void SysTick_CLKSourceConfig(rt_uint32_t SysTick_CLKSource)
  121. {
  122. /* Check the parameters */
  123. RT_ASSERT(IS_SYSTICK_CLK_SOURCE(SysTick_CLKSource));
  124. rt_uint32_t ctrl = SysTick->CTRL;
  125. ctrl &= ~SysTick_CLKSource_MASK;
  126. ctrl |= SysTick_CLKSource;
  127. SysTick->CTRL = ctrl;
  128. }
  129. /***************************************************************************//**
  130. * @brief
  131. * Configure the SysTick for OS tick.
  132. *
  133. * @details
  134. *
  135. * @note
  136. *
  137. ******************************************************************************/
  138. static void SysTick_Configuration(void)
  139. {
  140. #if defined(EFM32_USING_LFXO)
  141. /* LETIMER0 configurations */
  142. const LETIMER_Init_TypeDef letimerInit =
  143. {
  144. .enable = true, /* Start counting when init completed. */
  145. .debugRun = false, /* Counter shall not keep running during debug halt. */
  146. .rtcComp0Enable = false, /* Don't start counting on RTC COMP0 match. */
  147. .rtcComp1Enable = false, /* Don't start counting on RTC COMP1 match. */
  148. .comp0Top = true, /* Load COMP0 register into CNT when counter underflows. COMP is used as TOP */
  149. .bufTop = false, /* Don't load COMP1 into COMP0 when REP0 reaches 0. */
  150. .out0Pol = 0, /* Idle value for output 0. */
  151. .out1Pol = 0, /* Idle value for output 1. */
  152. .ufoa0 = letimerUFOANone, /* No output on output 0. */
  153. .ufoa1 = letimerUFOANone, /* No output on output 1. */
  154. .repMode = letimerRepeatFree /* Count until stopped by SW. */
  155. };
  156. CMU_ClockDivSet(cmuClock_LETIMER0, cmuClkDiv_8);
  157. CMU_ClockEnable(cmuClock_LETIMER0, true);
  158. LETIMER_CompareSet(LETIMER0, 0,
  159. EFM32_LETIMER_TOP_100HZ * RT_TICK_PER_SECOND / 100);
  160. /* Enable underflow interrupt */
  161. LETIMER_IntClear(LETIMER0, LETIMER_IF_UF);
  162. LETIMER_IntEnable(LETIMER0, LETIMER_IF_UF);
  163. /* Enable LETIMER0 interrupt vector in NVIC */
  164. NVIC_ClearPendingIRQ(LETIMER0_IRQn);
  165. NVIC_SetPriority(LETIMER0_IRQn, EFM32_IRQ_PRI_DEFAULT);
  166. NVIC_EnableIRQ(LETIMER0_IRQn);
  167. /* Start LETIMER0 */
  168. LETIMER_Init(LETIMER0, &letimerInit);
  169. #else
  170. rt_uint32_t coreClk;
  171. rt_uint32_t cnts;
  172. coreClk = SystemCoreClockGet();
  173. cnts = coreClk / RT_TICK_PER_SECOND;
  174. SysTick_Config(cnts);
  175. SysTick_CLKSourceConfig(SysTick_CLKSource_HFCORECLK);
  176. #endif
  177. }
  178. /***************************************************************************//**
  179. * @brief
  180. * Enable SWO.
  181. *
  182. * @details
  183. *
  184. * @note
  185. *
  186. ******************************************************************************/
  187. void Swo_Configuration(void)
  188. {
  189. rt_uint32_t *dwt_ctrl = (rt_uint32_t *) 0xE0001000;
  190. rt_uint32_t *tpiu_prescaler = (rt_uint32_t *) 0xE0040010;
  191. rt_uint32_t *tpiu_protocol = (rt_uint32_t *) 0xE00400F0;
  192. CMU->HFPERCLKEN0 |= CMU_HFPERCLKEN0_GPIO;
  193. /* Enable Serial wire output pin */
  194. GPIO->ROUTE |= GPIO_ROUTE_SWOPEN;
  195. #if defined(_EFM32_GIANT_FAMILY)
  196. /* Set location 0 */
  197. GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC0;
  198. /* Enable output on pin - GPIO Port F, Pin 2 */
  199. GPIO->P[5].MODEL &= ~(_GPIO_P_MODEL_MODE2_MASK);
  200. GPIO->P[5].MODEL |= GPIO_P_MODEL_MODE2_PUSHPULL;
  201. #else
  202. /* Set location 1 */
  203. GPIO->ROUTE = (GPIO->ROUTE & ~(_GPIO_ROUTE_SWLOCATION_MASK)) | GPIO_ROUTE_SWLOCATION_LOC1;
  204. /* Enable output on pin */
  205. GPIO->P[2].MODEH &= ~(_GPIO_P_MODEH_MODE15_MASK);
  206. GPIO->P[2].MODEH |= GPIO_P_MODEH_MODE15_PUSHPULL;
  207. #endif
  208. /* Enable debug clock AUXHFRCO */
  209. CMU->OSCENCMD = CMU_OSCENCMD_AUXHFRCOEN;
  210. while(!(CMU->STATUS & CMU_STATUS_AUXHFRCORDY));
  211. /* Enable trace in core debug */
  212. CoreDebug->DHCSR |= 1;
  213. CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
  214. /* Enable PC and IRQ sampling output */
  215. *dwt_ctrl = 0x400113FF;
  216. /* Set TPIU prescaler to 16. */
  217. *tpiu_prescaler = 0xf;
  218. /* Set protocol to NRZ */
  219. *tpiu_protocol = 2;
  220. /* Unlock ITM and output data */
  221. ITM->LAR = 0xC5ACCE55;
  222. ITM->TCR = 0x10009;
  223. }
  224. /***************************************************************************//**
  225. * @brief
  226. * Initialize the board.
  227. *
  228. * @details
  229. *
  230. * @note
  231. *
  232. ******************************************************************************/
  233. void rt_hw_board_init(void)
  234. {
  235. /* Chip errata */
  236. CHIP_Init();
  237. /* Initialize DVK board register access */
  238. #if defined(EFM32_GXXX_DK)
  239. DVK_init();
  240. #elif defined(EFM32GG_DK3750)
  241. DVK_init(DVK_Init_EBI);
  242. /* Disable all DVK interrupts */
  243. DVK_disableInterrupt(BC_INTEN_MASK);
  244. DVK_clearInterruptFlags(BC_INTFLAG_MASK);
  245. #endif
  246. /* config NVIC Configuration */
  247. NVIC_Configuration();
  248. #if defined(EFM32_USING_HFXO)
  249. /* Configure external oscillator */
  250. SystemHFXOClockSet(EFM32_HFXO_FREQUENCY);
  251. /* Switching the CPU clock source to HFXO */
  252. CMU_ClockSelectSet(cmuClock_HF, cmuSelect_HFXO);
  253. /* Turning off the high frequency RC Oscillator (HFRCO) */
  254. CMU_OscillatorEnable(cmuOsc_HFRCO, false, false);
  255. #endif
  256. #if defined(EFM32_USING_LFXO)
  257. CMU_ClockSelectSet(cmuClock_LFA,cmuSelect_LFXO);
  258. CMU_ClockSelectSet(cmuClock_LFB, cmuSelect_LFXO);
  259. #endif
  260. #if defined(EFM32_SWO_ENABLE)
  261. /* Enable SWO */
  262. Swo_Configuration();
  263. #endif
  264. /* Enable high frequency peripheral clock */
  265. CMU_ClockEnable(cmuClock_HFPER, true);
  266. /* Enabling clock to the interface of the low energy modules */
  267. CMU_ClockEnable(cmuClock_CORELE, true);
  268. /* Enable GPIO clock */
  269. CMU_ClockEnable(cmuClock_GPIO, true);
  270. /* Configure the SysTick */
  271. SysTick_Configuration();
  272. }
  273. /***************************************************************************//**
  274. * @brief
  275. * Initialize the hardware drivers.
  276. *
  277. * @details
  278. *
  279. * @note
  280. *
  281. ******************************************************************************/
  282. void rt_hw_driver_init(void)
  283. {
  284. /* Initialize DMA */
  285. rt_hw_dma_init();
  286. /* Select LFXO for specified module (and wait for it to stabilize) */
  287. #if (!defined(EFM32_USING_LFXO) && defined(RT_USING_RTC))
  288. #error "Low frequency clock source is needed for using RTC"
  289. #endif
  290. #if (!defined(EFM32_USING_LFXO )&& \
  291. (defined(RT_USING_LEUART0) || defined(RT_USING_LEUART1)))
  292. #error "Low frequency clock source is needed for using LEUART"
  293. #endif
  294. /* Initialize USART */
  295. #if (defined(RT_USING_USART0) || defined(RT_USING_USART1) || \
  296. defined(RT_USING_USART2) || defined(RT_USING_UART0) || \
  297. defined(RT_USING_UART1))
  298. rt_hw_usart_init();
  299. #endif
  300. /* Initialize LEUART */
  301. #if (defined(RT_USING_LEUART0) || defined(RT_USING_LEUART1))
  302. rt_hw_leuart_init();
  303. #endif
  304. /* Setup Console */
  305. #if defined(EFM32_GXXX_DK)
  306. DVK_enablePeripheral(DVK_RS232A);
  307. DVK_enablePeripheral(DVK_SPI);
  308. #elif defined(EFM32GG_DK3750)
  309. #if (RT_CONSOLE_DEVICE == EFM_UART1)
  310. DVK_enablePeripheral(DVK_RS232_UART);
  311. #elif (RT_CONSOLE_DEVICE == EFM_LEUART1)
  312. DVK_enablePeripheral(DVK_RS232_LEUART);
  313. #endif
  314. #endif
  315. rt_console_set_device(CONSOLE_DEVICE);
  316. /* Initialize Timer */
  317. #if (defined(RT_USING_TIMER0) || defined(RT_USING_TIMER1) || defined(RT_USING_TIMER2))
  318. rt_hw_timer_init();
  319. #endif
  320. /* Initialize ADC */
  321. #if defined(RT_USING_ADC0)
  322. rt_hw_adc_init();
  323. #endif
  324. /* Initialize ACMP */
  325. #if (defined(RT_USING_ACMP0) || defined(RT_USING_ACMP1))
  326. rt_hw_acmp_init();
  327. #endif
  328. /* Initialize IIC */
  329. #if (defined(RT_USING_IIC0) || defined(RT_USING_IIC1))
  330. rt_hw_iic_init();
  331. #endif
  332. /* Initialize RTC */
  333. #if defined(RT_USING_RTC)
  334. rt_hw_rtc_init();
  335. #endif
  336. /* Enable SPI access to MicroSD card */
  337. #if defined(EFM32_USING_SPISD)
  338. #if defined(EFM32_GXXX_DK)
  339. DVK_writeRegister(BC_SPI_CFG, 1);
  340. #elif defined(EFM32GG_DK3750)
  341. DVK_enablePeripheral(DVK_MICROSD);
  342. #endif
  343. #endif
  344. /* Enable SPI access to Ethernet */
  345. #if defined(EFM32_USING_ETHERNET)
  346. #if defined(EFM32GG_DK3750)
  347. DVK_enablePeripheral(DVK_ETH);
  348. #endif
  349. #endif
  350. /* Initialize LCD */
  351. #if defined(EFM32_USING_LCD)
  352. efm32_spiLcd_init();
  353. #endif
  354. /* Initialize Keys */
  355. #if defined(EFM32_USING_KEYS)
  356. #if defined(EFM32GG_DK3750)
  357. efm32_hw_keys_init();
  358. #endif
  359. #endif
  360. }
  361. /***************************************************************************//**
  362. * @}
  363. ******************************************************************************/