1
0

ls1c_timer.c 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. // 硬件定时器源码
  2. #include "ls1c_public.h"
  3. #include "ls1c_pin.h"
  4. #include "ls1c_clock.h"
  5. #include "ls1c_regs.h"
  6. #include "ls1c_pwm.h"
  7. #include "ls1c_timer.h"
  8. // 定时器中计数器(CNTR、HRC和LRC)的最大值
  9. #define TIMER_COUNTER_MAX (0xffffff)
  10. /*
  11. * 获取指定定时器的寄存器基地址
  12. * @timer 硬件定时器
  13. * @ret 基地址
  14. */
  15. unsigned int timer_get_reg_base(ls1c_timer_t timer)
  16. {
  17. unsigned int reg_base = 0;
  18. switch (timer)
  19. {
  20. case TIMER_PWM0:
  21. reg_base = LS1C_REG_BASE_PWM0;
  22. break;
  23. case TIMER_PWM1:
  24. reg_base = LS1C_REG_BASE_PWM1;
  25. break;
  26. case TIMER_PWM2:
  27. reg_base = LS1C_REG_BASE_PWM2;
  28. break;
  29. case TIMER_PWM3:
  30. reg_base = LS1C_REG_BASE_PWM3;
  31. break;
  32. }
  33. return reg_base;
  34. }
  35. /*
  36. * 初始化定时器,并开始定时
  37. * @timer_info 定时器和定时时间信息
  38. */
  39. void timer_init(timer_info_t *timer_info)
  40. {
  41. unsigned int timer_reg_base = 0; // 寄存器基地址
  42. unsigned long timer_clk = 0; // 硬件定时器的时钟
  43. unsigned long tmp;
  44. unsigned int ctrl = 0; // 控制寄存器中的控制信息
  45. // 判断入参
  46. if (NULL == timer_info)
  47. {
  48. return ;
  49. }
  50. /*
  51. * 把定时时间换算为计数器的值
  52. * 计数器值 = 定时器的时钟 * 定时时间(单位ns) / 1000000000
  53. * 龙芯1c的定时器时钟为APB时钟,达到126Mhz,
  54. * 为避免计算过程发生溢出,这里采用手动优化上面的计算式,也可以采用浮点运算
  55. */
  56. timer_clk = clk_get_apb_rate();
  57. tmp = (timer_clk / 1000000) * (timer_info->time_ns / 1000); // 将1000000000拆分为1000000和1000
  58. tmp = MIN(tmp, TIMER_COUNTER_MAX);
  59. // 控制寄存器信息
  60. ctrl = (1 << LS1C_PWM_INT_LRC_EN)
  61. | (0 << LS1C_PWM_INT_HRC_EN)
  62. | (0 << LS1C_PWM_CNTR_RST)
  63. | (0 << LS1C_PWM_INT_SR)
  64. | (1 << LS1C_PWM_INTEN)
  65. | (1 << LS1C_PWM_SINGLE)
  66. | (1 << LS1C_PWM_OE)
  67. | (1 << LS1C_PWM_CNT_EN);
  68. // 设置各个寄存器
  69. timer_reg_base = timer_get_reg_base(timer_info->timer); // 获取寄存器基地址
  70. reg_write_32(0, (volatile unsigned int *)(timer_reg_base + LS1C_PWM_HRC));
  71. reg_write_32(tmp--, (volatile unsigned int *)(timer_reg_base + LS1C_PWM_LRC));
  72. reg_write_32(0, (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CNTR));
  73. reg_write_32(ctrl, (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
  74. return ;
  75. }
  76. /*
  77. * 判断指定定时器是否超时(实现定时)
  78. * @timer_info 定时器
  79. * @ret TRUE or FALSE
  80. */
  81. BOOL timer_is_time_out(timer_info_t *timer_info)
  82. {
  83. unsigned int timer_reg_base = 0; // 寄存器基地址
  84. unsigned int ctrl; // 控制寄存器的值
  85. // 判断入参
  86. if (NULL == timer_info)
  87. {
  88. return FALSE;
  89. }
  90. // 读取控制寄存器
  91. timer_reg_base = timer_get_reg_base(timer_info->timer);
  92. ctrl = reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
  93. // 判断中断状态位
  94. if (ctrl & (1 << LS1C_PWM_INT_SR))
  95. {
  96. return TRUE;
  97. }
  98. else
  99. {
  100. return FALSE;
  101. }
  102. }
  103. /*
  104. * 停止定时器
  105. * @timer_info 定时器
  106. */
  107. void timer_stop(timer_info_t *timer_info)
  108. {
  109. unsigned int timer_reg_base = 0;
  110. // 判断入参
  111. if (NULL == timer_info)
  112. {
  113. return ;
  114. }
  115. timer_reg_base = timer_get_reg_base(timer_info->timer);
  116. reg_write_32(0, (volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL));
  117. return ;
  118. }
  119. /*
  120. * 获取定时器从初始化到现在的时间(实现计时功能),单位ns
  121. * @timer_info 硬件定时器
  122. * @ret 时间,单位ns
  123. */
  124. unsigned long timer_get_time_ns(timer_info_t *timer_info)
  125. {
  126. unsigned int timer_reg_base = 0;
  127. unsigned int cntr = 0; // 寄存器CNTR的值
  128. unsigned long time_ns = 0; // 时间,单位ns
  129. unsigned long timer_clk = 0; // 定时器时钟
  130. // 读取寄存器CNTR的值
  131. timer_reg_base = timer_get_reg_base(timer_info->timer);
  132. cntr = reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CNTR));
  133. /*
  134. * 将CNTR值换算为时间,单位us
  135. * 时间 = (计数器值CNTR * 1000000000) / 定时器时钟频率
  136. * 为避免产生溢出,手动优化上式为 时间 = (计数器值CNTR * 1000) / (定时器时钟频率 / 1000000)
  137. */
  138. timer_clk = clk_get_apb_rate();
  139. time_ns = (cntr * 1000 ) / (timer_clk /1000000);
  140. // rt_kprintf("[%s] time_us=%lu, cntr=%d, timer_clk=%d\n", __FUNCTION__, time_ns, cntr, timer_clk);
  141. return time_ns;
  142. }
  143. /*
  144. * 打印timer相关寄存器的值
  145. * @timer_info 硬件定时器
  146. */
  147. void timer_print_regs(timer_info_t *timer_info)
  148. {
  149. unsigned int timer_reg_base = 0;
  150. timer_reg_base = timer_get_reg_base(timer_info->timer);
  151. rt_kprintf("CNTR=0x%x, HRC=0x%x, LRC=0x%x, CTRL=0x%x\n",
  152. reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CNTR)),
  153. reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_HRC)),
  154. reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_LRC)),
  155. reg_read_32((volatile unsigned int *)(timer_reg_base + LS1C_PWM_CTRL)));
  156. return ;
  157. }