drv_hwtimer.c 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-10-30 ChuShicheng first version
  9. */
  10. #include "drv_hwtimer.h"
  11. #include "board.h"
  12. #ifdef BSP_USING_HWTIMER
  13. #define DBG_LEVEL DBG_LOG
  14. #include <rtdbg.h>
  15. #define LOG_TAG "DRV.HWTIMER"
  16. typedef struct _timer
  17. {
  18. char *name;
  19. struct repeating_timer repeat_timer;
  20. alarm_id_t alarm_id;
  21. rt_hwtimer_t timer;
  22. }_timer_t;
  23. static void _hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state);
  24. static rt_err_t _hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode);
  25. static void _hwtimer_stop(rt_hwtimer_t *timer);
  26. static rt_uint32_t _hwtimer_count_get(rt_hwtimer_t *timer);
  27. static rt_err_t _hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args);
  28. static int64_t _hwtmr_isr(alarm_id_t id, void *user_data);
  29. static const struct rt_hwtimer_ops _hwtimer_ops = {
  30. .init = _hwtimer_init,
  31. .start = _hwtimer_start,
  32. .stop = _hwtimer_stop,
  33. .count_get = _hwtimer_count_get,
  34. .control = _hwtimer_control
  35. };
  36. static const struct rt_hwtimer_info _hwtimer_info = {
  37. .maxfreq = 1000000UL,
  38. .minfreq = 1000000UL,
  39. .maxcnt = 0xFFFF,
  40. .cntmode = HWTIMER_MODE_PERIOD
  41. };
  42. #ifdef BSP_USING_TIMER0
  43. static _timer_t timer0 = {.name = "timer0"};
  44. #endif /* BSP_USING_TIMER0 */
  45. #ifdef BSP_USING_TIMER1
  46. static _timer_t timer1 = {.name = "timer1" };
  47. #endif /* BSP_USING_TIMER1 */
  48. #ifdef BSP_USING_TIMER2
  49. static _timer_t timer2 = {.name = "timer2"};
  50. #endif /* BSP_USING_TIMER2 */
  51. #ifdef BSP_USING_TIMER3
  52. static _timer_t timer3 = {.name = "timer3" };
  53. #endif /* BSP_USING_TIMER3 */
  54. static _timer_t *_timer_obj[] = {
  55. #ifdef BSP_USING_TIMER0
  56. &timer0,
  57. #endif /* BSP_USING_TIMER0 */
  58. #ifdef BSP_USING_TIMER1
  59. &timer1,
  60. #endif /* BSP_USING_TIMER1 */
  61. #ifdef BSP_USING_TIMER2
  62. &timer2,
  63. #endif /* BSP_USING_TIMER2 */
  64. #ifdef BSP_USING_TIMER3
  65. &timer3,
  66. #endif /* BSP_USING_TIMER3 */
  67. };
  68. static int64_t _hwtmr_isr(alarm_id_t id, void *user_data)
  69. {
  70. _timer_t *_tmr = rt_container_of(id, _timer_t, alarm_id);
  71. rt_device_hwtimer_isr(&_tmr->timer);
  72. return RT_TRUE;
  73. }
  74. static bool _repeat_timer_isr(struct repeating_timer *t)
  75. {
  76. _timer_t *_tmr = rt_container_of(t, _timer_t, repeat_timer);
  77. rt_device_hwtimer_isr(&_tmr->timer);
  78. return RT_TRUE;
  79. }
  80. static void _hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  81. {
  82. }
  83. static rt_err_t _hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
  84. {
  85. _timer_t *_tmr = rt_container_of(timer, _timer_t, timer);
  86. if(mode == HWTIMER_MODE_ONESHOT)
  87. _tmr->alarm_id = add_alarm_in_us(cnt, _hwtmr_isr, RT_NULL, RT_TRUE);
  88. else
  89. add_repeating_timer_us(cnt, _repeat_timer_isr, RT_NULL, &_tmr->repeat_timer);
  90. return RT_EOK;
  91. }
  92. static void _hwtimer_stop(rt_hwtimer_t *timer)
  93. {
  94. _timer_t *_tmr = rt_container_of(timer, _timer_t, timer);
  95. if(timer->mode == HWTIMER_MODE_ONESHOT)
  96. cancel_alarm(_tmr->alarm_id);
  97. else
  98. cancel_repeating_timer(&_tmr->repeat_timer);
  99. }
  100. static rt_uint32_t _hwtimer_count_get(rt_hwtimer_t *timer)
  101. {
  102. _timer_t *_tmr = rt_container_of(timer, _timer_t, timer);
  103. return timer_hw->alarm[_tmr->alarm_id];
  104. }
  105. static rt_err_t _hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
  106. {
  107. rt_err_t err = RT_EOK;
  108. _timer_t *_tmr = rt_container_of(timer, _timer_t, timer);
  109. switch (cmd)
  110. {
  111. case HWTIMER_CTRL_FREQ_SET:
  112. err = -RT_ERROR;
  113. break;
  114. case HWTIMER_CTRL_INFO_GET:
  115. *(rt_hwtimer_t*)args = _tmr->timer;
  116. break;
  117. case HWTIMER_CTRL_MODE_SET:
  118. _tmr->timer.mode = *(rt_uint32_t*)args;
  119. break;
  120. case HWTIMER_CTRL_STOP:
  121. _hwtimer_stop(timer);
  122. break;
  123. }
  124. return err;
  125. }
  126. int rt_hw_hwtimer_init(void)
  127. {
  128. int ret = RT_EOK;
  129. for (uint32_t i = 0; i < sizeof(_timer_obj) / sizeof(_timer_obj[0]); i++)
  130. {
  131. _timer_obj[i]->timer.info = &_hwtimer_info;
  132. _timer_obj[i]->timer.ops = &_hwtimer_ops;
  133. ret = rt_device_hwtimer_register(&_timer_obj[i]->timer, _timer_obj[i]->name, _timer_obj[i]);
  134. if (ret != RT_EOK)
  135. {
  136. LOG_E("%s register failed", _timer_obj[i]->name);
  137. }
  138. }
  139. return ret;
  140. }
  141. INIT_DEVICE_EXPORT(rt_hw_hwtimer_init);
  142. #endif /* BSP_USING_HWTIMER */