drv_hwtimer.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. /*
  2. * Copyright (c) 2006-2018, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2015-09-02 heyuanjie87 the first version
  9. */
  10. #include <rtthread.h>
  11. #include <rtdevice.h>
  12. #include <board.h>
  13. #include "drv_hwtimer.h"
  14. #ifdef RT_USING_HWTIMER
  15. static void NVIC_Configuration(void)
  16. {
  17. NVIC_InitTypeDef NVIC_InitStructure;
  18. /* Enable the TIM5 global Interrupt */
  19. NVIC_InitStructure.NVIC_IRQChannel = TIM2_IRQn;
  20. NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0x00;
  21. NVIC_InitStructure.NVIC_IRQChannelSubPriority = 0x00;
  22. NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;
  23. NVIC_Init(&NVIC_InitStructure);
  24. }
  25. static void timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  26. {
  27. TIM_TypeDef *tim;
  28. tim = (TIM_TypeDef *)timer->parent.user_data;
  29. TIM_DeInit(tim);
  30. if (state == 1)
  31. {
  32. NVIC_Configuration();
  33. RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM2, ENABLE);
  34. TIM_CounterModeConfig(tim, TIM_CounterMode_Up);
  35. }
  36. }
  37. static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
  38. {
  39. TIM_TypeDef *tim;
  40. uint16_t m;
  41. tim = (TIM_TypeDef *)timer->parent.user_data;
  42. TIM_SetAutoreload(tim, t);
  43. m = (opmode == HWTIMER_MODE_ONESHOT)? TIM_OPMode_Single : TIM_OPMode_Repetitive;
  44. TIM_SelectOnePulseMode(tim, m);
  45. TIM_Cmd(tim, ENABLE);
  46. return RT_EOK;
  47. }
  48. static void timer_stop(rt_hwtimer_t *timer)
  49. {
  50. TIM_TypeDef *tim;
  51. tim = (TIM_TypeDef *)timer->parent.user_data;
  52. TIM_Cmd(tim, DISABLE);
  53. }
  54. static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
  55. {
  56. TIM_TypeDef *tim;
  57. rt_err_t err = RT_EOK;
  58. tim = (TIM_TypeDef *)timer->parent.user_data;
  59. switch (cmd)
  60. {
  61. case HWTIMER_CTRL_FREQ_SET:
  62. {
  63. RCC_ClocksTypeDef clk;
  64. uint16_t val;
  65. rt_uint32_t freq;
  66. RCC_GetClocksFreq(&clk);
  67. freq = *((rt_uint32_t*)arg);
  68. clk.PCLK1_Frequency *= 2;
  69. val = clk.PCLK1_Frequency/freq;
  70. TIM_ITConfig(tim, TIM_IT_Update, DISABLE);
  71. TIM_PrescalerConfig(tim, val - 1, TIM_PSCReloadMode_Immediate);
  72. TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  73. TIM_ITConfig(tim, TIM_IT_Update, ENABLE);
  74. }
  75. break;
  76. default:
  77. {
  78. err = -RT_ENOSYS;
  79. }
  80. break;
  81. }
  82. return err;
  83. }
  84. static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer)
  85. {
  86. TIM_TypeDef *tim;
  87. tim = (TIM_TypeDef *)timer->parent.user_data;
  88. return TIM_GetCounter(tim);
  89. }
  90. static const struct rt_hwtimer_info _info =
  91. {
  92. 1000000, /* the maximum count frequency can be set */
  93. 2000, /* the minimum count frequency can be set */
  94. 0xFFFF, /* the maximum counter value */
  95. HWTIMER_CNTMODE_UP,/* Increment or Decreasing count mode */
  96. };
  97. static const struct rt_hwtimer_ops _ops =
  98. {
  99. timer_init,
  100. timer_start,
  101. timer_stop,
  102. timer_counter_get,
  103. timer_ctrl,
  104. };
  105. static rt_hwtimer_t _timer0;
  106. int stm32_hwtimer_init(void)
  107. {
  108. _timer0.info = &_info;
  109. _timer0.ops = &_ops;
  110. rt_device_hwtimer_register(&_timer0, "timer0", TIM2);
  111. return 0;
  112. }
  113. void TIM2_IRQHandler(void)
  114. {
  115. if (TIM_GetITStatus(TIM2, TIM_IT_Update) != RESET)
  116. {
  117. TIM_ClearITPendingBit(TIM2, TIM_IT_Update);
  118. rt_device_hwtimer_isr(&_timer0);
  119. }
  120. }
  121. INIT_BOARD_EXPORT(stm32_hwtimer_init);
  122. #endif