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