drv_timer.c 7.0 KB

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