drv_timer.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266
  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 * (HFXO_FREQUENCY / (1 << TMR_CFG_PRESCALER) / 1000))
  28. /* Private variables ------------------------------------------------------------*/
  29. #ifdef RT_USING_TIMER2
  30. static struct rt_device timer2_device;
  31. #endif
  32. /* Private function prototypes ---------------------------------------------------*/
  33. /* Private functions ------------------------------------------------------------*/
  34. /******************************************************************//**
  35. * @brief
  36. * Initialize Timer device
  37. *
  38. * @details
  39. *
  40. * @note
  41. *
  42. * @param[in] dev
  43. * Pointer to device descriptor
  44. *
  45. * @return
  46. * Error code
  47. *********************************************************************/
  48. static rt_err_t rt_hs_timer_init (rt_device_t dev)
  49. {
  50. RT_ASSERT(dev != RT_NULL);
  51. struct efm32_timer_device_t *timer;
  52. RT_ASSERT(dev != RT_NULL);
  53. timer = (struct efm32_timer_device_t *)(dev->user_data);
  54. timer->hook.cbFunc = RT_NULL;
  55. timer->hook.userPtr = RT_NULL;
  56. return RT_EOK;
  57. }
  58. /******************************************************************//**
  59. * @brief
  60. * Configure Timer device
  61. *
  62. * @details
  63. *
  64. * @note
  65. *
  66. * @param[in] dev
  67. * Pointer to device descriptor
  68. *
  69. * @param[in] cmd
  70. * Timer control command
  71. *
  72. * @param[in] args
  73. * Arguments
  74. *
  75. * @return
  76. * Error code
  77. *********************************************************************/
  78. static rt_err_t rt_hs_timer_control (
  79. rt_device_t dev,
  80. rt_uint8_t cmd,
  81. void *args)
  82. {
  83. struct efm32_timer_device_t *timer;
  84. RT_ASSERT(dev != RT_NULL);
  85. timer = (struct efm32_timer_device_t *)(dev->user_data);
  86. switch (cmd)
  87. {
  88. case RT_DEVICE_CTRL_SUSPEND:
  89. /* Suspend device */
  90. dev->flag |= RT_DEVICE_FLAG_SUSPENDED;
  91. TIMER_Enable(timer->timer_device, false);
  92. break;
  93. case RT_DEVICE_CTRL_RESUME:
  94. /* Resume device */
  95. dev->flag &= ~RT_DEVICE_FLAG_SUSPENDED;
  96. TIMER_Enable(timer->timer_device, true);
  97. break;
  98. case RT_DEVICE_CTRL_TIMER:
  99. {
  100. /* change device setting */
  101. struct efm32_timer_control_t *control;
  102. control = (struct efm32_timer_control_t *)args;
  103. TIMER_Enable(timer->timer_device, false);
  104. timer->timer_device->CNT = _TIMER_CNT_RESETVALUE;
  105. TIMER_TopSet(timer->timer_device, TIMER_TopCalculate(control->period));
  106. timer->hook.cbFunc = control->hook.cbFunc;
  107. timer->hook.userPtr = control->hook.userPtr;
  108. TIMER_Enable(timer->timer_device, true);
  109. }
  110. break;
  111. }
  112. return RT_EOK;
  113. }
  114. /******************************************************************//**
  115. * @brief
  116. * Register Timer device
  117. *
  118. * @details
  119. *
  120. * @note
  121. *
  122. * @param[in] device
  123. * Pointer to device descriptor
  124. *
  125. * @param[in] name
  126. * Device name
  127. *
  128. * @param[in] flag
  129. * Configuration flags
  130. *
  131. * @param[in] timer
  132. * Pointer to Timer device descriptor
  133. *
  134. * @return
  135. * Error code
  136. *********************************************************************/
  137. rt_err_t rt_hw_timer_register(
  138. rt_device_t device,
  139. const char *name,
  140. rt_uint32_t flag,
  141. struct efm32_timer_device_t *timer)
  142. {
  143. RT_ASSERT(device != RT_NULL);
  144. device->type = RT_Device_Class_Char; /* fixme: should be timer type*/
  145. device->rx_indicate = RT_NULL;
  146. device->tx_complete = RT_NULL;
  147. device->init = rt_hs_timer_init;
  148. device->open = RT_NULL;
  149. device->close = RT_NULL;
  150. device->read = RT_NULL;
  151. device->write = RT_NULL;
  152. device->control = rt_hs_timer_control;
  153. device->user_data = timer;
  154. /* register a character device */
  155. return rt_device_register(device, name, flag);
  156. }
  157. /******************************************************************//**
  158. * @brief
  159. * Timer counter overflow interrupt handler
  160. *
  161. * @details
  162. *
  163. * @note
  164. *********************************************************************/
  165. void rt_hw_timer_isr(rt_device_t dev)
  166. {
  167. struct efm32_timer_device_t *timer;
  168. RT_ASSERT(dev != RT_NULL);
  169. timer = (struct efm32_timer_device_t *)(dev->user_data);
  170. if (timer->hook.cbFunc != RT_NULL)
  171. {
  172. (timer->hook.cbFunc)(timer->hook.userPtr);
  173. }
  174. }
  175. /******************************************************************//**
  176. * @brief
  177. * Initialize all Timer module related hardware and register Timer device to kernel
  178. *
  179. * @details
  180. *
  181. * @note
  182. *********************************************************************/
  183. void rt_hw_timer_init(void)
  184. {
  185. struct efm32_timer_device_t *timer;
  186. TIMER_Init_TypeDef init;
  187. efm32_irq_hook_init_t hook;
  188. /* Set TIMERn parameters */
  189. init.enable = false;
  190. init.debugRun = true;
  191. init.prescale = TMR_CFG_PRESCALER;
  192. init.clkSel = timerClkSelHFPerClk;
  193. init.fallAction = timerInputActionNone;
  194. init.riseAction = timerInputActionNone;
  195. init.mode = timerModeUp;
  196. init.dmaClrAct = false;
  197. init.quadModeX4 = false;
  198. init.oneShot = false;
  199. init.sync = false;
  200. #ifdef RT_USING_TIMER2
  201. timer = rt_malloc(sizeof(struct efm32_timer_device_t));
  202. if (timer == RT_NULL)
  203. {
  204. rt_kprintf("no memory for TIMER driver\n");
  205. return;
  206. }
  207. timer->timer_device = TIMER2;
  208. /* Enable clock for TIMERn module */
  209. CMU_ClockEnable(cmuClock_TIMER2, true);
  210. /* Reset */
  211. TIMER_Reset(TIMER2);
  212. /* Configure TIMER */
  213. TIMER_Init(TIMER2, &init);
  214. hook.type = efm32_irq_type_timer;
  215. hook.unit = 2;
  216. hook.cbFunc = rt_hw_timer_isr;
  217. hook.userPtr = &timer2_device;
  218. efm32_irq_hook_register(&hook);
  219. /* Enable overflow interrupt */
  220. TIMER_IntEnable(TIMER2, TIMER_IF_OF);
  221. TIMER_IntClear(TIMER2, TIMER_IF_OF);
  222. /* Enable TIMERn interrupt vector in NVIC */
  223. NVIC_ClearPendingIRQ(TIMER2_IRQn);
  224. NVIC_SetPriority(TIMER2_IRQn, EFM32_IRQ_PRI_DEFAULT);
  225. NVIC_EnableIRQ(TIMER2_IRQn);
  226. rt_hw_timer_register(&timer2_device, RT_TIMER2_NAME, 0, timer);
  227. #endif
  228. }
  229. /******************************************************************//**
  230. * @}
  231. *********************************************************************/