wm_timer.c 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279
  1. /**
  2. * @file wm_timer.c
  3. *
  4. * @brief Timer Driver Module
  5. *
  6. * @author dave
  7. *
  8. * Copyright (c) 2014 Winner Microelectronics Co., Ltd.
  9. */
  10. #include "wm_type_def.h"
  11. #include "wm_timer.h"
  12. #include "wm_regs.h"
  13. #include "wm_irq.h"
  14. #include "wm_cpu.h"
  15. #include "wm_pmu.h"
  16. #include "tls_common.h"
  17. enum tls_timer_id{
  18. TLS_TIMER_ID_0 = 0,
  19. TLS_TIMER_ID_1,
  20. TLS_TIMER_ID_2,
  21. TLS_TIMER_ID_3,
  22. TLS_TIMER_ID_4,
  23. TLS_TIMER_ID_5,
  24. TLS_TIMER_ID_MAX
  25. };
  26. struct timer_irq_context {
  27. tls_timer_irq_callback callback;
  28. void *arg;
  29. };
  30. static struct timer_irq_context timer_context[TLS_TIMER_ID_MAX] = {{0,0}};
  31. static u8 wm_timer_bitmap = 0;
  32. #if 0
  33. static void timer_clear_irq(int timer_id)
  34. {
  35. volatile u8 i;
  36. volatile u32 value;
  37. value = tls_reg_read32(HR_TIMER0_5_CSR);
  38. for (i = TLS_TIMER_ID_0; i < TLS_TIMER_ID_MAX; i++)
  39. {
  40. value &= ~(TLS_TIMER_INT_CLR(i));
  41. }
  42. tls_reg_write32(HR_TIMER0_5_CSR, value | TLS_TIMER_INT_CLR(timer_id));
  43. }
  44. #endif
  45. static void timer_irq_callback(void *p)
  46. {
  47. u8 timer_id;
  48. timer_id = (u8)(u32)p;
  49. //timer_clear_irq(timer_id);
  50. if (NULL != timer_context[timer_id].callback)
  51. timer_context[timer_id].callback(timer_context[timer_id].arg);
  52. return;
  53. }
  54. void TIMER0_5_IRQHandler(void)
  55. {
  56. u32 timer_csr = tls_reg_read32(HR_TIMER0_5_CSR);
  57. tls_reg_write32(HR_TIMER0_5_CSR, timer_csr);
  58. if(timer_csr & TLS_TIMER_INT_CLR(0))
  59. {
  60. timer_irq_callback((void *)TLS_TIMER_ID_0);
  61. }
  62. if(timer_csr & TLS_TIMER_INT_CLR(1))
  63. {
  64. timer_irq_callback((void *)TLS_TIMER_ID_1);
  65. }
  66. if(timer_csr & TLS_TIMER_INT_CLR(2))
  67. {
  68. timer_irq_callback((void *)TLS_TIMER_ID_2);
  69. }
  70. if(timer_csr & TLS_TIMER_INT_CLR(3))
  71. {
  72. timer_irq_callback((void *)TLS_TIMER_ID_3);
  73. }
  74. if(timer_csr & TLS_TIMER_INT_CLR(4))
  75. {
  76. timer_irq_callback((void *)TLS_TIMER_ID_4);
  77. }
  78. if(timer_csr & TLS_TIMER_INT_CLR(5))
  79. {
  80. timer_irq_callback((void *)TLS_TIMER_ID_5);
  81. }
  82. }
  83. /**
  84. * @brief This function is used to create the timer
  85. *
  86. * @param[in] cfg timer configuration
  87. *
  88. * @retval WM_TIMER_ID_INVALID failed
  89. * @retval other timer id[0~5]
  90. *
  91. * @note
  92. * user not need clear interrupt flag.
  93. * timer callback function is called in interrupt,
  94. * so can not operate the critical data in the callback fuuction,
  95. * recommendation to send messages to other tasks to operate it.
  96. */
  97. u8 tls_timer_create(struct tls_timer_cfg *cfg)
  98. {
  99. u8 i;
  100. int timer_csr;
  101. for (i = 0; i < TLS_TIMER_ID_MAX; i++)
  102. {
  103. if (!(wm_timer_bitmap & BIT(i)))
  104. break;
  105. }
  106. if (TLS_TIMER_ID_MAX == i)
  107. {
  108. return WM_TIMER_ID_INVALID;
  109. }
  110. if (wm_timer_bitmap == 0)
  111. {
  112. tls_open_peripheral_clock(TLS_PERIPHERAL_TYPE_TIMER);
  113. }
  114. wm_timer_bitmap |= BIT(i);
  115. timer_context[i].callback = cfg->callback;
  116. timer_context[i].arg = cfg->arg;
  117. tls_sys_clk sysclk;
  118. tls_sys_clk_get(&sysclk);
  119. tls_reg_write32(HR_TIMER_CFG, sysclk.apbclk-1);
  120. timer_csr = tls_reg_read32(HR_TIMER0_5_CSR);
  121. if (!cfg->is_repeat)
  122. timer_csr |= TLS_TIMER_ONE_TIME(i);
  123. else
  124. timer_csr &= ~(TLS_TIMER_ONE_TIME(i));
  125. if (TLS_TIMER_UNIT_MS == cfg->unit)
  126. timer_csr |= TLS_TIMER_MS_UNIT(i);
  127. else
  128. timer_csr &= ~(TLS_TIMER_MS_UNIT(i));
  129. tls_reg_write32(HR_TIMER0_5_CSR, timer_csr | TLS_TIMER_INT_CLR(i));
  130. if(cfg->timeout){
  131. tls_reg_write32(HR_TIMER0_PRD + 0x04 * i, cfg->timeout);
  132. }
  133. tls_irq_enable(TIMER_IRQn);
  134. return i;
  135. }
  136. /**
  137. * @brief This function is used to start the timer
  138. *
  139. * @param[in] timer_id timer id[0~5]
  140. *
  141. * @return None
  142. *
  143. * @note None
  144. */
  145. void tls_timer_start(u8 timer_id)
  146. {
  147. if (!(wm_timer_bitmap & BIT(timer_id)))
  148. return;
  149. tls_reg_write32(HR_TIMER0_5_CSR, tls_reg_read32(HR_TIMER0_5_CSR)|TLS_TIMER_INT_EN(timer_id)| TLS_TIMER_EN(timer_id));
  150. return;
  151. }
  152. /**
  153. * @brief This function is used to stop the timer
  154. *
  155. * @param[in] timer_id timer id[0~5]
  156. *
  157. * @return None
  158. *
  159. * @note None
  160. */
  161. void tls_timer_stop(u8 timer_id)
  162. {
  163. if (!(wm_timer_bitmap & BIT(timer_id)))
  164. return;
  165. tls_reg_write32(HR_TIMER0_5_CSR, tls_reg_read32(HR_TIMER0_5_CSR)|TLS_TIMER_INT_CLR(timer_id));
  166. tls_reg_write32(HR_TIMER0_5_CSR, tls_reg_read32(HR_TIMER0_5_CSR) &~ TLS_TIMER_EN(timer_id));
  167. return;
  168. }
  169. /**
  170. * @brief This function is used to change a timer wait time
  171. *
  172. * @param[in] timer_id timer id[0~5]
  173. *
  174. * @param[in] newtime new wait time
  175. *
  176. * @retval None
  177. *
  178. * @note If the timer does not start, this function will start the timer
  179. */
  180. void tls_timer_change(u8 timer_id, u32 newtime)
  181. {
  182. if (!(wm_timer_bitmap & BIT(timer_id)))
  183. return;
  184. tls_timer_stop(timer_id);
  185. if (newtime)
  186. tls_reg_write32(HR_TIMER0_PRD + 0x04 * timer_id, newtime);
  187. tls_timer_start(timer_id);
  188. return;
  189. }
  190. /**
  191. * @brief This function is used to read a timer's current value
  192. *
  193. * @param[in] timer_id timer id[0~5]
  194. *
  195. * @retval timer's current value
  196. *
  197. * @note none
  198. */
  199. u32 tls_timer_read(u8 timer_id)
  200. {
  201. u32 value;
  202. if (!(wm_timer_bitmap & BIT(timer_id)))
  203. {
  204. return 0;
  205. }
  206. value = tls_reg_read32(HR_TIMER0_CNT + 0x04 * timer_id);
  207. return value;
  208. }
  209. /**
  210. * @brief This function is used to delete the timer
  211. *
  212. * @param[in] timer_id timer id[0~5]
  213. *
  214. * @return None
  215. *
  216. * @note None
  217. */
  218. void tls_timer_destroy(u8 timer_id)
  219. {
  220. if (!(wm_timer_bitmap & BIT(timer_id)))
  221. return;
  222. tls_timer_stop(timer_id);
  223. timer_context[timer_id].callback = NULL;
  224. timer_context[timer_id].arg = NULL;
  225. wm_timer_bitmap &= ~BIT(timer_id);
  226. if (wm_timer_bitmap == 0)
  227. {
  228. tls_close_peripheral_clock(TLS_PERIPHERAL_TYPE_TIMER);
  229. }
  230. return;
  231. }