drv_hwtimer.c 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  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 "lpc_timer.h"
  17. #include "lpc_clkpwr.h"
  18. #include "drv_hwtimer.h"
  19. #ifdef RT_USING_HWTIMER
  20. static void NVIC_Configuration(void)
  21. {
  22. NVIC_EnableIRQ(TIMER0_IRQn);
  23. }
  24. static void timer_init(rt_hwtimer_t *timer, rt_uint32_t state)
  25. {
  26. LPC_TIM_TypeDef *tim;
  27. TIM_TIMERCFG_Type cfg;
  28. tim = (LPC_TIM_TypeDef *)timer->parent.user_data;
  29. TIM_DeInit(tim);
  30. if (state == 1)
  31. {
  32. NVIC_Configuration();
  33. cfg.PrescaleOption = TIM_PRESCALE_TICKVAL;
  34. cfg.PrescaleValue = 0xFFFF;
  35. TIM_Init(tim, TIM_TIMER_MODE, &cfg);
  36. }
  37. }
  38. static rt_err_t timer_start(rt_hwtimer_t *timer, rt_uint32_t t, rt_hwtimer_mode_t opmode)
  39. {
  40. LPC_TIM_TypeDef *tim;
  41. TIM_MATCHCFG_Type match;
  42. tim = (LPC_TIM_TypeDef *)timer->parent.user_data;
  43. match.MatchChannel = 0;
  44. match.IntOnMatch = ENABLE;
  45. match.ResetOnMatch = ENABLE;
  46. match.StopOnMatch = (opmode == HWTIMER_MODE_ONESHOT)? ENABLE : DISABLE;
  47. match.ExtMatchOutputType = 0;
  48. match.MatchValue = t;
  49. TIM_ConfigMatch(tim, &match);
  50. TIM_Cmd(tim, ENABLE);
  51. return RT_EOK;
  52. }
  53. static void timer_stop(rt_hwtimer_t *timer)
  54. {
  55. LPC_TIM_TypeDef *tim;
  56. tim = (LPC_TIM_TypeDef *)timer->parent.user_data;
  57. TIM_Cmd(tim, DISABLE);
  58. }
  59. static rt_err_t timer_ctrl(rt_hwtimer_t *timer, rt_uint32_t cmd, void *arg)
  60. {
  61. LPC_TIM_TypeDef *tim;
  62. rt_err_t err = RT_EOK;
  63. tim = (LPC_TIM_TypeDef *)timer->parent.user_data;
  64. switch (cmd)
  65. {
  66. case HWTIMER_CTRL_FREQ_SET:
  67. {
  68. uint32_t clk;
  69. uint32_t pre;
  70. clk = CLKPWR_GetCLK(CLKPWR_CLKTYPE_PER);
  71. pre = clk / *((uint32_t*)arg) - 1;
  72. tim->PR = pre;
  73. }
  74. break;
  75. default:
  76. {
  77. err = -RT_ENOSYS;
  78. }
  79. break;
  80. }
  81. return err;
  82. }
  83. static rt_uint32_t timer_counter_get(rt_hwtimer_t *timer)
  84. {
  85. LPC_TIM_TypeDef *tim;
  86. tim = (LPC_TIM_TypeDef *)timer->parent.user_data;
  87. return tim->TC;
  88. }
  89. static const struct rt_hwtimer_info _info =
  90. {
  91. 1000000, /* the maximum count frequency can be set */
  92. 2000, /* the minimum count frequency can be set */
  93. 0xFFFFFF, /* the maximum counter value */
  94. HWTIMER_CNTMODE_UP,/* Increment or Decreasing count mode */
  95. };
  96. static const struct rt_hwtimer_ops _ops =
  97. {
  98. timer_init,
  99. timer_start,
  100. timer_stop,
  101. timer_counter_get,
  102. timer_ctrl,
  103. };
  104. static rt_hwtimer_t _timer0;
  105. int lpc_hwtimer_init(void)
  106. {
  107. _timer0.info = &_info;
  108. _timer0.ops = &_ops;
  109. rt_device_hwtimer_register(&_timer0, "timer0", LPC_TIM0);
  110. return 0;
  111. }
  112. void TIMER0_IRQHandler(void)
  113. {
  114. if (TIM_GetIntStatus(LPC_TIM0, TIM_MR0_INT) != RESET)
  115. {
  116. TIM_ClearIntPending(LPC_TIM0, TIM_MR0_INT);
  117. rt_device_hwtimer_isr(&_timer0);
  118. }
  119. }
  120. INIT_BOARD_EXPORT(lpc_hwtimer_init);
  121. #endif