timer.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364
  1. /* Copyright 2018 Canaan Inc.
  2. *
  3. * Licensed under the Apache License, Version 2.0 (the "License");
  4. * you may not use this file except in compliance with the License.
  5. * You may obtain a copy of the License at
  6. *
  7. * http://www.apache.org/licenses/LICENSE-2.0
  8. *
  9. * Unless required by applicable law or agreed to in writing, software
  10. * distributed under the License is distributed on an "AS IS" BASIS,
  11. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. * See the License for the specific language governing permissions and
  13. * limitations under the License.
  14. */
  15. #include <syslog.h>
  16. #include "io.h"
  17. #include "plic.h"
  18. #include "stddef.h"
  19. #include "sysctl.h"
  20. #include "timer.h"
  21. #include "utils.h"
  22. /**
  23. * @brief Private definitions for the timer instance
  24. */
  25. typedef struct timer_instance
  26. {
  27. timer_device_number_t device;
  28. timer_channel_number_t channel;
  29. timer_callback_t callback;
  30. void *ctx;
  31. bool single_shot;
  32. } timer_instance_t;
  33. volatile timer_instance_t timer_instance[TIMER_DEVICE_MAX][TIMER_CHANNEL_MAX];
  34. volatile kendryte_timer_t *const timer[3] =
  35. {
  36. (volatile kendryte_timer_t *)TIMER0_BASE_ADDR,
  37. (volatile kendryte_timer_t *)TIMER1_BASE_ADDR,
  38. (volatile kendryte_timer_t *)TIMER2_BASE_ADDR};
  39. void timer_init(timer_device_number_t timer_number)
  40. {
  41. for(size_t i = 0; i < TIMER_CHANNEL_MAX; i++)
  42. timer_instance[timer_number][i] = (const timer_instance_t){
  43. .device = 0,
  44. .channel = 0,
  45. .callback = NULL,
  46. .ctx = NULL,
  47. .single_shot = 0,
  48. };
  49. sysctl_clock_enable(SYSCTL_CLOCK_TIMER0 + timer_number);
  50. }
  51. void timer_set_clock_div(timer_device_number_t timer_number, uint32_t div)
  52. {
  53. sysctl_clock_set_threshold(timer_number == 0 ? SYSCTL_THRESHOLD_TIMER0 : timer_number == 1 ? SYSCTL_THRESHOLD_TIMER1 : SYSCTL_THRESHOLD_TIMER2, div);
  54. }
  55. void timer_enable(timer_device_number_t timer_number, timer_channel_number_t channel)
  56. {
  57. timer[timer_number]->channel[channel].control |= TIMER_CR_ENABLE;
  58. }
  59. void timer_disable(timer_device_number_t timer_number, timer_channel_number_t channel)
  60. {
  61. timer[timer_number]->channel[channel].control &= (~TIMER_CR_ENABLE);
  62. }
  63. void timer_enable_pwm(timer_device_number_t timer_number, timer_channel_number_t channel)
  64. {
  65. timer[timer_number]->channel[channel].control |= TIMER_CR_PWM_ENABLE;
  66. }
  67. void timer_disable_pwm(timer_device_number_t timer_number, timer_channel_number_t channel)
  68. {
  69. timer[timer_number]->channel[channel].control &= (~TIMER_CR_PWM_ENABLE);
  70. }
  71. void timer_enable_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel)
  72. {
  73. timer[timer_number]->channel[channel].control &= (~TIMER_CR_INTERRUPT_MASK);
  74. }
  75. void timer_disable_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel)
  76. {
  77. timer[timer_number]->channel[channel].control |= TIMER_CR_INTERRUPT_MASK;
  78. }
  79. void timer_set_mode(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t mode)
  80. {
  81. timer[timer_number]->channel[channel].control &= (~TIMER_CR_MODE_MASK);
  82. timer[timer_number]->channel[channel].control |= mode;
  83. }
  84. void timer_set_reload(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t count)
  85. {
  86. timer[timer_number]->channel[channel].load_count = count;
  87. }
  88. void timer_set_reload2(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t count)
  89. {
  90. timer[timer_number]->load_count2[channel] = count;
  91. }
  92. uint32_t timer_get_count(timer_device_number_t timer_number, timer_channel_number_t channel)
  93. {
  94. return timer[timer_number]->channel[channel].current_value;
  95. }
  96. uint32_t timer_get_reload(timer_device_number_t timer_number, timer_channel_number_t channel)
  97. {
  98. return timer[timer_number]->channel[channel].load_count;
  99. }
  100. uint32_t timer_get_reload2(timer_device_number_t timer_number, timer_channel_number_t channel)
  101. {
  102. return timer[timer_number]->load_count2[channel];
  103. }
  104. uint32_t timer_get_interrupt_status(timer_device_number_t timer_number)
  105. {
  106. return timer[timer_number]->intr_stat;
  107. }
  108. uint32_t timer_get_raw_interrupt_status(timer_device_number_t timer_number)
  109. {
  110. return timer[timer_number]->raw_intr_stat;
  111. }
  112. uint32_t timer_channel_get_interrupt_status(timer_device_number_t timer_number, timer_channel_number_t channel)
  113. {
  114. return timer[timer_number]->channel[channel].intr_stat;
  115. }
  116. void timer_clear_interrupt(timer_device_number_t timer_number)
  117. {
  118. timer[timer_number]->eoi = timer[timer_number]->eoi;
  119. }
  120. void timer_channel_clear_interrupt(timer_device_number_t timer_number, timer_channel_number_t channel)
  121. {
  122. timer[timer_number]->channel[channel].eoi = timer[timer_number]->channel[channel].eoi;
  123. }
  124. void timer_set_enable(timer_device_number_t timer_number, timer_channel_number_t channel, uint32_t enable)
  125. {
  126. if(enable)
  127. timer[timer_number]->channel[channel].control = TIMER_CR_USER_MODE | TIMER_CR_ENABLE;
  128. else
  129. timer[timer_number]->channel[channel].control = TIMER_CR_INTERRUPT_MASK;
  130. }
  131. size_t timer_set_interval(timer_device_number_t timer_number, timer_channel_number_t channel, size_t nanoseconds)
  132. {
  133. uint32_t clk_freq = sysctl_clock_get_freq(SYSCTL_CLOCK_TIMER0 + timer_number);
  134. double min_step = 1e9 / clk_freq;
  135. size_t value = (size_t)(nanoseconds / min_step);
  136. configASSERT(value > 0 && value < UINT32_MAX);
  137. timer[timer_number]->channel[channel].load_count = (uint32_t)value;
  138. return (size_t)(min_step * value);
  139. }
  140. typedef void (*timer_ontick)();
  141. timer_ontick time_irq[3][4] = {NULL};
  142. static int timer_isr(void *parm)
  143. {
  144. uint32_t timer_number;
  145. for(timer_number = 0; timer_number < 3; timer_number++)
  146. {
  147. if(parm == timer[timer_number])
  148. break;
  149. }
  150. uint32_t channel = timer[timer_number]->intr_stat;
  151. size_t i = 0;
  152. for(i = 0; i < 4; i++)
  153. {
  154. if(channel & 1)
  155. {
  156. if(time_irq[timer_number][i])
  157. (time_irq[timer_number][i])();
  158. break;
  159. }
  160. channel >>= 1;
  161. }
  162. readl(&timer[timer_number]->eoi);
  163. return 0;
  164. }
  165. void timer_set_irq(timer_device_number_t timer_number, timer_channel_number_t channel, void (*func)(), uint32_t priority)
  166. {
  167. time_irq[timer_number][channel] = func;
  168. if(channel < 2)
  169. {
  170. plic_set_priority(IRQN_TIMER0A_INTERRUPT + timer_number * 2, priority);
  171. plic_irq_register(IRQN_TIMER0A_INTERRUPT + timer_number * 2, timer_isr, (void *)timer[timer_number]);
  172. plic_irq_enable(IRQN_TIMER0A_INTERRUPT + timer_number * 2);
  173. } else
  174. {
  175. plic_set_priority(IRQN_TIMER0B_INTERRUPT + timer_number * 2, priority);
  176. plic_irq_register(IRQN_TIMER0B_INTERRUPT + timer_number * 2, timer_isr, (void *)timer[timer_number]);
  177. plic_irq_enable(IRQN_TIMER0B_INTERRUPT + timer_number * 2);
  178. }
  179. }
  180. /**
  181. * @brief Get the timer irqn by device and channel object
  182. *
  183. * @note Internal function, not public
  184. * @param device The device
  185. * @param channel The channel
  186. * @return plic_irq_t IRQ number
  187. */
  188. static plic_irq_t get_timer_irqn_by_device_and_channel(timer_device_number_t device, timer_channel_number_t channel)
  189. {
  190. if(device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX)
  191. {
  192. /*
  193. * Select timer interrupt part
  194. * Hierarchy of Timer interrupt to PLIC
  195. * +---------+ +-----------+
  196. * | 0+----+ | |
  197. * | | +--+0A |
  198. * | 1+----+ | |
  199. * | TIMER0 | | |
  200. * | 2+----+ | |
  201. * | | +--+0B |
  202. * | 3+----+ | |
  203. * +---------+ | |
  204. * | |
  205. * +---------+ | |
  206. * | 0+----+ | |
  207. * | | +--+1A |
  208. * | 1+----+ | |
  209. * | TIMER1 | | PLIC |
  210. * | 2+----+ | |
  211. * | | +--+1B |
  212. * | 3+----+ | |
  213. * +---------+ | |
  214. * | |
  215. * +---------+ | |
  216. * | 0+----+ | |
  217. * | | +--+2A |
  218. * | 1+----+ | |
  219. * | TIMER2 | | |
  220. * | 2+----+ | |
  221. * | | +--+2B |
  222. * | 3+----+ | |
  223. * +---------+ +-----------+
  224. *
  225. */
  226. if(channel < 2)
  227. {
  228. /* It is part A interrupt, offset + 0 */
  229. return IRQN_TIMER0A_INTERRUPT + device * 2;
  230. } else
  231. {
  232. /* It is part B interrupt, offset + 1 */
  233. return IRQN_TIMER0B_INTERRUPT + device * 2;
  234. }
  235. }
  236. return IRQN_NO_INTERRUPT;
  237. }
  238. /**
  239. * @brief Process user callback function
  240. *
  241. * @note Internal function, not public
  242. * @param ctx The context
  243. * @return int The callback result
  244. */
  245. static int timer_interrupt_handler(void *ctx)
  246. {
  247. timer_instance_t *instance = (timer_instance_t *)ctx;
  248. timer_device_number_t device = instance->device;
  249. timer_channel_number_t channel = instance->channel;
  250. uint32_t channel_int_stat = timer[device]->intr_stat;
  251. uint32_t irq_channel = (channel >> 1) << 1;
  252. channel_int_stat >>= irq_channel;
  253. for(size_t i = irq_channel; i < irq_channel + 2; i++)
  254. {
  255. /* Check every bit for interrupt status */
  256. if(channel_int_stat & 1)
  257. {
  258. if(timer_instance[device][i].callback)
  259. {
  260. /* Process user callback function */
  261. timer_instance[device][i].callback(timer_instance[device][i].ctx);
  262. /* Check if this timer is a single shot timer */
  263. if(timer_instance[device][i].single_shot)
  264. {
  265. /* Single shot timer, disable it */
  266. timer_set_enable(device, i, 0);
  267. }
  268. }
  269. /* Clear timer interrupt flag for specific channel */
  270. readl(&timer[device]->channel[i].eoi);
  271. }
  272. channel_int_stat >>= 1;
  273. }
  274. /*
  275. * NOTE:
  276. * Don't read timer[device]->eoi here, or you will lost some interrupt
  277. * readl(&timer[device]->eoi);
  278. */
  279. return 0;
  280. }
  281. int timer_irq_register(timer_device_number_t device, timer_channel_number_t channel, int is_single_shot, uint32_t priority, timer_callback_t callback, void *ctx)
  282. {
  283. if(device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX)
  284. {
  285. plic_irq_t irq_number = get_timer_irqn_by_device_and_channel(device, channel);
  286. timer_instance[device][channel] = (const timer_instance_t){
  287. .device = device,
  288. .channel = channel,
  289. .callback = callback,
  290. .ctx = ctx,
  291. .single_shot = is_single_shot,
  292. };
  293. plic_set_priority(irq_number, priority);
  294. plic_irq_register(irq_number, timer_interrupt_handler, (void *)&timer_instance[device][channel]);
  295. plic_irq_enable(irq_number);
  296. return 0;
  297. }
  298. return -1;
  299. }
  300. int timer_irq_unregister(timer_device_number_t device, timer_channel_number_t channel)
  301. {
  302. if(device < TIMER_DEVICE_MAX && channel < TIMER_CHANNEL_MAX)
  303. {
  304. timer_instance[device][channel] = (const timer_instance_t){
  305. .device = 0,
  306. .channel = 0,
  307. .callback = NULL,
  308. .ctx = NULL,
  309. .single_shot = 0,
  310. };
  311. /* Combine 0 and 1 to A interrupt, 2 and 3 to B interrupt */
  312. if((!(timer_instance[device][TIMER_CHANNEL_0].callback ||
  313. timer_instance[device][TIMER_CHANNEL_1].callback)) ||
  314. (!(timer_instance[device][TIMER_CHANNEL_2].callback ||
  315. timer_instance[device][TIMER_CHANNEL_3].callback)))
  316. {
  317. plic_irq_t irq_number = get_timer_irqn_by_device_and_channel(device, channel);
  318. plic_irq_unregister(irq_number);
  319. }
  320. return 0;
  321. }
  322. return -1;
  323. }