drv_timer.c 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326
  1. /******************************************************************//**
  2. * @file drv_timer.c
  3. * @brief USART driver 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 LICENSE in this
  10. * distribution or at http://www.rt-thread.org/license/LICENSE
  11. **********************************************************************
  12. * @section Change Logs
  13. * Date Author Notes
  14. * 2011-01-18 onelife Initial creation for EFM32
  15. *********************************************************************/
  16. /******************************************************************//**
  17. * @addtogroup efm32
  18. * @{
  19. *********************************************************************/
  20. /* Includes -------------------------------------------------------------------*/
  21. #include "board.h"
  22. #include "drv_timer.h"
  23. /* Private typedef -------------------------------------------------------------*/
  24. /* Private define --------------------------------------------------------------*/
  25. /* Private macro --------------------------------------------------------------*/
  26. #define TIMER_TopCalculate(p) \
  27. (p * (EFM32_HFXO_FREQUENCY / (1 << TMR_CFG_PRESCALER) / 1000))
  28. /* Private variables ------------------------------------------------------------*/
  29. #ifdef RT_USING_TIMER1
  30. static struct rt_device timer1_device;
  31. #endif
  32. #ifdef RT_USING_TIMER2
  33. static struct rt_device timer2_device;
  34. #endif
  35. /* Private function prototypes ---------------------------------------------------*/
  36. /* Private functions ------------------------------------------------------------*/
  37. /******************************************************************//**
  38. * @brief
  39. * Initialize Timer device
  40. *
  41. * @details
  42. *
  43. * @note
  44. *
  45. * @param[in] dev
  46. * Pointer to device descriptor
  47. *
  48. * @return
  49. * Error code
  50. *********************************************************************/
  51. static rt_err_t rt_hs_timer_init (rt_device_t dev)
  52. {
  53. RT_ASSERT(dev != RT_NULL);
  54. struct efm32_timer_device_t *timer;
  55. timer = (struct efm32_timer_device_t *)(dev->user_data);
  56. timer->hook.cbFunc = RT_NULL;
  57. timer->hook.userPtr = RT_NULL;
  58. return RT_EOK;
  59. }
  60. /******************************************************************//**
  61. * @brief
  62. * Configure Timer device
  63. *
  64. * @details
  65. *
  66. * @note
  67. *
  68. * @param[in] dev
  69. * Pointer to device descriptor
  70. *
  71. * @param[in] cmd
  72. * Timer control command
  73. *
  74. * @param[in] args
  75. * Arguments
  76. *
  77. * @return
  78. * Error code
  79. *********************************************************************/
  80. static rt_err_t rt_hs_timer_control (
  81. rt_device_t dev,
  82. rt_uint8_t cmd,
  83. void *args)
  84. {
  85. RT_ASSERT(dev != RT_NULL);
  86. struct efm32_timer_device_t *timer;
  87. timer = (struct efm32_timer_device_t *)(dev->user_data);
  88. switch (cmd)
  89. {
  90. case RT_DEVICE_CTRL_SUSPEND:
  91. /* Suspend device */
  92. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  93. TIMER_Enable(timer->timer_device, false);
  94. break;
  95. case RT_DEVICE_CTRL_RESUME:
  96. /* Resume device */
  97. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  98. TIMER_Enable(timer->timer_device, true);
  99. break;
  100. case RT_DEVICE_CTRL_TIMER_PERIOD:
  101. {
  102. /* change device setting */
  103. struct efm32_timer_control_t *control;
  104. rt_uint32_t running;
  105. control = (struct efm32_timer_control_t *)args;
  106. running = timer->timer_device->STATUS & 0x00000001;
  107. TIMER_Enable(timer->timer_device, false);
  108. timer->timer_device->CNT = _TIMER_CNT_RESETVALUE;
  109. TIMER_TopSet(timer->timer_device, TIMER_TopCalculate(control->period));
  110. timer->hook.cbFunc = control->hook.cbFunc;
  111. timer->hook.userPtr = control->hook.userPtr;
  112. if (running)
  113. {
  114. TIMER_Enable(timer->timer_device, true);
  115. }
  116. }
  117. break;
  118. }
  119. return RT_EOK;
  120. }
  121. /******************************************************************//**
  122. * @brief
  123. * Register Timer device
  124. *
  125. * @details
  126. *
  127. * @note
  128. *
  129. * @param[in] device
  130. * Pointer to device descriptor
  131. *
  132. * @param[in] name
  133. * Device name
  134. *
  135. * @param[in] flag
  136. * Configuration flags
  137. *
  138. * @param[in] timer
  139. * Pointer to Timer device descriptor
  140. *
  141. * @return
  142. * Error code
  143. *********************************************************************/
  144. rt_err_t rt_hw_timer_register(
  145. rt_device_t device,
  146. const char *name,
  147. rt_uint32_t flag,
  148. struct efm32_timer_device_t *timer)
  149. {
  150. RT_ASSERT(device != RT_NULL);
  151. device->type = RT_Device_Class_Char; /* fixme: should be timer type*/
  152. device->rx_indicate = RT_NULL;
  153. device->tx_complete = RT_NULL;
  154. device->init = rt_hs_timer_init;
  155. device->open = RT_NULL;
  156. device->close = RT_NULL;
  157. device->read = RT_NULL;
  158. device->write = RT_NULL;
  159. device->control = rt_hs_timer_control;
  160. device->user_data = timer;
  161. /* register a character device */
  162. return rt_device_register(device, name, flag);
  163. }
  164. /******************************************************************//**
  165. * @brief
  166. * Timer counter overflow interrupt handler
  167. *
  168. * @details
  169. *
  170. * @note
  171. *********************************************************************/
  172. void rt_hw_timer_isr(rt_device_t dev)
  173. {
  174. RT_ASSERT(dev != RT_NULL);
  175. struct efm32_timer_device_t *timer;
  176. timer = (struct efm32_timer_device_t *)(dev->user_data);
  177. if (timer->hook.cbFunc != RT_NULL)
  178. {
  179. (timer->hook.cbFunc)(timer->hook.userPtr);
  180. }
  181. }
  182. /******************************************************************//**
  183. * @brief
  184. * Initialize all Timer module related hardware and register Timer device to kernel
  185. *
  186. * @details
  187. *
  188. * @note
  189. *********************************************************************/
  190. void rt_hw_timer_init(void)
  191. {
  192. struct efm32_timer_device_t *timer;
  193. TIMER_Init_TypeDef init;
  194. efm32_irq_hook_init_t hook;
  195. /* Set TIMERn parameters */
  196. init.enable = false;
  197. init.debugRun = true;
  198. init.prescale = TMR_CFG_PRESCALER;
  199. init.clkSel = timerClkSelHFPerClk;
  200. init.fallAction = timerInputActionNone;
  201. init.riseAction = timerInputActionNone;
  202. init.mode = timerModeUp;
  203. init.dmaClrAct = false;
  204. init.quadModeX4 = false;
  205. init.oneShot = false;
  206. init.sync = false;
  207. #ifdef RT_USING_TIMER1
  208. timer = rt_malloc(sizeof(struct efm32_timer_device_t));
  209. if (timer == RT_NULL)
  210. {
  211. #ifdef RT_TIMER_DEBUG
  212. rt_kprintf("no memory for TIMER1 driver\n");
  213. #endif
  214. return;
  215. }
  216. timer->timer_device = TIMER1;
  217. #if (RT_USING_TIMER1 == RT_TIMER_ONCE)
  218. init.oneShot = true;
  219. #elif (RT_USING_TIMER1 == RT_TIMER_CONTINUE)
  220. init.oneShot = false;
  221. #endif
  222. /* Enable clock for TIMERn module */
  223. CMU_ClockEnable(cmuClock_TIMER1, true);
  224. /* Reset */
  225. TIMER_Reset(TIMER1);
  226. /* Configure TIMER */
  227. TIMER_Init(TIMER1, &init);
  228. hook.type = efm32_irq_type_timer;
  229. hook.unit = 1;
  230. hook.cbFunc = rt_hw_timer_isr;
  231. hook.userPtr = &timer1_device;
  232. efm32_irq_hook_register(&hook);
  233. /* Enable overflow interrupt */
  234. TIMER_IntEnable(TIMER1, TIMER_IF_OF);
  235. TIMER_IntClear(TIMER1, TIMER_IF_OF);
  236. /* Enable TIMERn interrupt vector in NVIC */
  237. NVIC_ClearPendingIRQ(TIMER1_IRQn);
  238. NVIC_SetPriority(TIMER1_IRQn, EFM32_IRQ_PRI_DEFAULT);
  239. NVIC_EnableIRQ(TIMER1_IRQn);
  240. rt_hw_timer_register(&timer1_device, RT_TIMER1_NAME, 0, timer);
  241. #endif
  242. #ifdef RT_USING_TIMER2
  243. timer = rt_malloc(sizeof(struct efm32_timer_device_t));
  244. if (timer == RT_NULL)
  245. {
  246. #ifdef RT_TIMER_DEBUG
  247. rt_kprintf("no memory for TIMER2 driver\n");
  248. #endif
  249. return;
  250. }
  251. timer->timer_device = TIMER2;
  252. #if (RT_USING_TIMER2 == RT_TIMER_ONCE)
  253. init.oneShot = true;
  254. #elif (RT_USING_TIMER2 == RT_TIMER_CONTINUE)
  255. init.oneShot = false;
  256. #endif
  257. /* Enable clock for TIMERn module */
  258. CMU_ClockEnable(cmuClock_TIMER2, true);
  259. /* Reset */
  260. TIMER_Reset(TIMER2);
  261. /* Configure TIMER */
  262. TIMER_Init(TIMER2, &init);
  263. hook.type = efm32_irq_type_timer;
  264. hook.unit = 2;
  265. hook.cbFunc = rt_hw_timer_isr;
  266. hook.userPtr = &timer2_device;
  267. efm32_irq_hook_register(&hook);
  268. /* Enable overflow interrupt */
  269. TIMER_IntEnable(TIMER2, TIMER_IF_OF);
  270. TIMER_IntClear(TIMER2, TIMER_IF_OF);
  271. /* Enable TIMERn interrupt vector in NVIC */
  272. NVIC_ClearPendingIRQ(TIMER2_IRQn);
  273. NVIC_SetPriority(TIMER2_IRQn, EFM32_IRQ_PRI_DEFAULT);
  274. NVIC_EnableIRQ(TIMER2_IRQn);
  275. rt_hw_timer_register(&timer2_device, RT_TIMER2_NAME, 0, timer);
  276. #endif
  277. }
  278. /******************************************************************//**
  279. * @}
  280. *********************************************************************/