drv_hwtimer.c 3.5 KB

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