drv_hwtimer.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166
  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-11-15 BetMul first version
  9. */
  10. #include "drv_hwtimer.h"
  11. #include <rtthread.h>
  12. #include <rtdevice.h>
  13. #include "driver/gptimer.h"
  14. #include "sdkconfig.h"
  15. #ifdef RT_USING_HWTIMER
  16. /**
  17. * handle interrupt for hwtimer.
  18. */
  19. static bool mcu_hwtimer_intr_handler(gptimer_handle_t gptimer, const gptimer_alarm_event_data_t *edata, void *user_ctx)
  20. {
  21. rt_interrupt_enter();
  22. rt_hwtimer_t *hwtimer = (rt_hwtimer_t *)user_ctx;
  23. rt_device_hwtimer_isr(hwtimer);
  24. rt_interrupt_leave();
  25. return 0;
  26. }
  27. /**
  28. * init the hwtimer
  29. */
  30. static void mcu_hwtimer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  31. {
  32. gptimer_handle_t gptimer = (gptimer_handle_t)timer->parent.user_data;
  33. // let the gptimer into enable status
  34. ESP_ERROR_CHECK(gptimer_enable(gptimer));
  35. }
  36. /**
  37. * start the hwtimer, change status into running
  38. */
  39. static rt_err_t mcu_hwtimer_start(rt_hwtimer_t *timer, rt_uint32_t cnt, rt_hwtimer_mode_t mode)
  40. {
  41. gptimer_handle_t gptimer = (gptimer_handle_t)timer->parent.user_data;
  42. gptimer_alarm_config_t alarm_config = {
  43. .alarm_count = cnt,
  44. };
  45. if (mode == HWTIMER_MODE_ONESHOT)
  46. {
  47. }
  48. else
  49. {
  50. alarm_config.reload_count = 0;
  51. alarm_config.flags.auto_reload_on_alarm = true;
  52. }
  53. ESP_ERROR_CHECK(gptimer_set_alarm_action(gptimer, &alarm_config));
  54. ESP_ERROR_CHECK(gptimer_start(gptimer));
  55. return RT_EOK;
  56. }
  57. /**
  58. * stop the hwtimer, change the status from running into enable
  59. */
  60. static void mcu_hwtimer_stop(rt_hwtimer_t *timer)
  61. {
  62. gptimer_handle_t gptimer = (gptimer_handle_t)timer->parent.user_data;
  63. ESP_ERROR_CHECK(gptimer_stop(gptimer));
  64. }
  65. /**
  66. * get count
  67. */
  68. static rt_uint32_t mcu_hwtimer_count_get(rt_hwtimer_t *timer)
  69. {
  70. gptimer_handle_t gptimer = (gptimer_handle_t)timer->parent.user_data;
  71. // get count number
  72. uint64_t value;
  73. ESP_ERROR_CHECK(gptimer_get_raw_count(gptimer, &value));
  74. return (rt_uint32_t)value;
  75. }
  76. /**
  77. * control the hwtimer
  78. */
  79. static rt_err_t mcu_hwtimer_control(rt_hwtimer_t *timer, rt_uint32_t cmd, void *args)
  80. {
  81. rt_err_t err = RT_EOK;
  82. switch (cmd)
  83. {
  84. case HWTIMER_CTRL_FREQ_SET:
  85. err = -RT_ERROR;
  86. break;
  87. case HWTIMER_CTRL_INFO_GET:
  88. err = -RT_ERROR;
  89. break;
  90. case HWTIMER_CTRL_MODE_SET:
  91. timer->mode = *(rt_uint32_t *)args;
  92. break;
  93. case HWTIMER_CTRL_STOP:
  94. mcu_hwtimer_stop(timer);
  95. break;
  96. }
  97. return err;
  98. }
  99. static struct rt_hwtimer_device _hwtimer;
  100. static const struct rt_hwtimer_ops _hwtimer_ops =
  101. {
  102. .init = mcu_hwtimer_init,
  103. .start = mcu_hwtimer_start,
  104. .stop = mcu_hwtimer_stop,
  105. .count_get = mcu_hwtimer_count_get,
  106. .control = mcu_hwtimer_control};
  107. static const struct rt_hwtimer_info _hwtimer_info =
  108. {
  109. // TODO:what is the true max and min?
  110. .maxfreq = 1000000UL,
  111. .minfreq = 1000000UL,
  112. .maxcnt = 0xFFFF,
  113. .cntmode = HWTIMER_MODE_ONESHOT};
  114. int rt_hw_hwtimer_init(void)
  115. {
  116. char *name = "timer0";
  117. gptimer_handle_t gptimer = NULL;
  118. gptimer_config_t timer_config = {
  119. .clk_src = GPTIMER_CLK_SRC_DEFAULT,
  120. .direction = GPTIMER_COUNT_UP,
  121. .resolution_hz = 1 * 1000 * 1000,
  122. };
  123. gptimer_event_callbacks_t cbs = {
  124. .on_alarm = mcu_hwtimer_intr_handler,
  125. };
  126. ESP_ERROR_CHECK(gptimer_new_timer(&timer_config, &gptimer));
  127. ESP_ERROR_CHECK(gptimer_register_event_callbacks(gptimer, &cbs, &_hwtimer));
  128. _hwtimer.info = &_hwtimer_info;
  129. _hwtimer.ops = &_hwtimer_ops;
  130. return rt_device_hwtimer_register(&_hwtimer, name, (void *)gptimer);
  131. }
  132. INIT_DEVICE_EXPORT(rt_hw_hwtimer_init);
  133. #endif /* RT_USING_HWTIMER */